Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WARNING, Unable to connect to 'https://myurl/myserver'. Cloud code and push notifications may be unavailable! #4506

Closed
notiles opened this issue Jan 17, 2018 · 16 comments

Comments

@notiles
Copy link

notiles commented Jan 17, 2018

Issue Description

When I launch my parse server I got a warning
WARNING, Unable to connect to 'https://my.url/myserver/'. Cloud code and push notifications may be unavailable!

But my server is running, I can see datas, edit and read them in my parse dashboard and console.log put in cloud code file works.

I don't use push notification so I can't test them...

A precision, I change the domain name recently and change from a self signed certificate (letsencrypt) to a commercial certificate.

But every configuration linked to the old domain has been deleted in nginx and in every files linked to parse (I think so...)

I launch my parse server with pm2 and ecosystem.json :

{
  "apps" : [{
    "name"        : "parse-wrapper",
    "script"      : "server.js",
    "watch"       : false,
    "merge_logs"  : true,
    "cwd"         : "/home/parse"
  }]
}

and server.js :

var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var path = require('path');
var app = express();

var api = new ParseServer({
  databaseURI: 'mongodb://user:pwd@my.url:mgport/ddb?ssl=true', 
  cloud: '/home/parse/cloud/main.js',
  verbose: true,
  appId: 'xxx',
  masterKey: 'xxx',
  restApiKey:'xxx',
  javascriptKey:'xxx',
  clientKey:'xxx',
  fileKey: 'xxx',
  serverURL: 'https://my.url/parse/',
  liveQuery: {
    classNames: ['MyClass']
  }
});

app.use('/parse/', api);
var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
    console.log('parse-server running on port ' + port + '.');
    ParseServer.createLiveQueryServer(httpServer);
});

EDIT : I fix the issue by using http instead of https in the serverURL parameter and using localhost instead of the domain url, but I don't understand why, it was working before with https with my old domain name
serverURL: 'http://localhost:1337/parse/'

Steps to reproduce

launch the server task with PM2

Expected Results

No warning...

Actual Outcome

get a warning

Environment Setup

  • Server

    • parse-server version (Be specific! Don't say 'latest'.) : 2.7.1
    • Operating System: Ubuntu 14.04 nvm & node 9.4.0
    • Hardware: DigitalOcean 1GB Memory
    • Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): DigitalOcean
  • Database

    • MongoDB version: 3.0.15
    • Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): DigitalOcean

Logs/Trace

WARNING, Unable to connect to 'https://my.url/myserver/'. Cloud code and push notifications may be unavailable!

@Biromain
Copy link

Biromain commented Jan 17, 2018

I have this issue too.
Seem come from src/ParseServer.js#L267.
My localhost/health and <reverseProxyUrl>/health responses are httpCode: 200 and body {"status":"ok"}

  • No PM2 just a webpack build
  • Docker container
  • Traefik reverse proxy container

@flovilmart
Copy link
Contributor

flovilmart commented Jan 17, 2018 via email

@Biromain
Copy link

Biromain commented Jan 17, 2018

After try/catch :
json = { status: 'ok' }
response.statusCode = 200

When i run same test externaly of parse-server (gulp file for imports & tests), test seems ok oO
For me, it's just a false positive. parse-server seem just not able to call himself externaly.

Edit
Warning is display on server boot only and job with the test is ok.

Parse.Cloud.job("health_check", function(request, status) {
  if(Parse.serverURL) {
    const request = require('request');
    request(Parse.serverURL.replace(/\/$/, "") + "/health", function (error, response, body) {
      let json;
      try {
        json = JSON.parse(body);
      } catch(e) {
        json = null;
      }
      if (error || response.statusCode !== 200 || !json || json && json.status !== 'ok') {
        status.error(`👎 error: ${error}, statusCode: ${response.statusCode}, body: ${body}`);
      } else {
        status.success("👍");
      }
    });
  }else {
    status.error("👎 No Parse server URL found");
  }
});

Job is ok.

@notiles
Copy link
Author

notiles commented Jan 17, 2018

Thanks, I also confirm that https://my.url/myserver/health return a json { status: 'ok' }

So it look like a false positive but still weird...

@Biromain
Copy link

As long as /health check is good and orchestrator dont kill process, it's good for me. But still weird.

@flovilmart
Copy link
Contributor

perhaps the on('mount') event occurs too early, therefore, the call fails at startup.

@notiles
Copy link
Author

notiles commented Jan 18, 2018

I don't know if it's a consequence but I can't connect to the parse server form nodejs.

It works fine with CURL or with the dashboard API Console... Any idea?

var Parse = require('parse/node');

Parse.initialize("APP ID");
Parse.serverURL = 'https://my.url.xx/parse';

const LabelsObject = Parse.Object.extend('ClassName');
const labelsQuery = new Parse.Query(LabelsObject);
console.log('LabelsQuery...');
labelsQuery.find().then((labs) => {
  console.log('LABELS FOUND');
  console.log(labs);
}).catch((e) => {
  console.log(e);
});
ParseError {
  code: 100,
  message: 'XMLHttpRequest failed: "Unable to connect to the Parse API"' }

@Biromain
Copy link

Your dashboard/script is on same domain?
Because i has been same issue caused by CrossDomain limitation.

@notiles
Copy link
Author

notiles commented Jan 18, 2018

I find my error... It was a wrong ssl setup. I forgot to make a bundle certificate... Everything work perfectly now. Sorry for the wasting time

@notiles notiles closed this as completed Jan 18, 2018
@flovilmart
Copy link
Contributor

@notlies, this warning was actually very helpful indeed :) do you want to add a line to the parse server guide in the docs repo about this particular behavior? This may help other users

@notiles
Copy link
Author

notiles commented Jan 18, 2018

No problem to add a line in the parse server guide, but it was just a bad ssl configuration.

I simply forgot this step below and directly use your_domain_name.crt instead of the bundle.crt.

Concatenate the primary and intermediate certificates
You need to concatenate your primary certificate file (your_domain_name.crt) and the intermediate certificate file (DigiCertCA.crt) into a single .crt file.
To concatenate the files, run the following command:
cat your_domain_name.crt DigiCertCA.crt >> bundle.crt

This cause the server to run perfectly without visuals error (Chrome validate the certificate and dashboard was perfectly running like CURL commands) But I understand the error when we tried to relaunch my nodejs script...

@flovilmart
Copy link
Contributor

Perhaps the line could read just that, in the tune of that this warning may be emitted when https is incorrectly configured.

@daksh019
Copy link

daksh019 commented Jul 3, 2018

I faced this issue and this might help someone in the future.

Note that this is one of the reasons why this warning might be thrown. This is for parse server version: 2.8.2

To create your own standalone parse server, using express, the basic steps involved are close to:

  1. Create a parse-server object with all your config like. For example: const api = new ParseServer(config);
  2. config will contain the server URL along with all other requirements.
  3. Create an express app object. For example: const app = express();
  4. Then mount the parse server API on the express like -> app.use(mountPath, api);
  5. Then create the server like: const httpServer = require('http').createServer(app);
  6. Then start listening on a port like: httpServer.listen(port);

As soon as the mount is called, the parse-server will verify the url mentioned in the config by making a request to /health endpoint.

If for some reason there is a delay in listening to the port (point 6) after mounting the API (point 4), then the above warning will be thrown.

For example, in one case I was establishing a mongoose connection and only then started listening to the port. Because of this, the verification of URL from parse server failed, although everything worked fine after that.

And one of the possible solutions is to get done with all such work before mounting the Parse API and ensuring no delay between mounting and listening to the port as described above.

While this may not be the exact steps for everyone the idea is that:

parse server will call verify URL on the server URL mentioned in the configs.

And if there is a delay in starting the server after you have mounted the parse Apis, the above warning will be thrown.

Hope it helps.

@karthikSmartserv
Copy link

Well when this happens, spend whole day and night debugging it. Cry for sometime thinking you are failure and finally give up and go to sleep. Next day reboot the system it will work properly .
Worked for me, not sure about others

@gnowland
Copy link

gnowland commented Sep 20, 2020

My WARNING, Unable to connect to 'https://localhost:1337/api'. Cloud code and push notifications may be unavailable! error was caused by the following verifyServerUrl function

if (error || response.statusCode !== 200 || !json || json && json.status !== 'ok') {
value for response:

{ Error: unable to verify the first certificate
    at TLSSocket.onConnectSecure (_tls_wrap.js:1049:34)
    at TLSSocket.emit (events.js:182:13)
    at TLSSocket.EventEmitter.emit (domain.js:442:20)
    at TLSSocket._finishInit (_tls_wrap.js:631:8) code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' }

Of course this is happening because I'm trying to serve localhost data with a self-signed certificate.

Any help on solving this would be so greatly appreciated!

@gnowland
Copy link

gnowland commented Sep 21, 2020

Ok. I got the error message to go away, but I'm not really sure if this is the most advisable way. Seeing as this only applies to development I don't think it carries any risk, but it's worth mentioning that setting
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' in a production environment is a very bad idea as @flovilmart states in parse-community/parse-dashboard#429 (comment)

In my case I was trying to use a self-signed certificate on localhost to serve the parse-server based app over HTTPS, so this is what I ended up with:

let parseServer;
if (process.env.NODE_ENV !== 'production') {
  process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
  var certs = {
    key: fs.readFileSync('./ssl/localhost.key'),
    cert: fs.readFileSync('./ssl/localhost.crt'),
  }
  parseServer = require('https').createServer(certs, app)
} else {
  parseServer = require('http').createServer(app)
}

Also, be sure to include app.use after the readFileSync calls above to avoid any delay between mounting and listening per @daksh019

app.use(process.env.PARSE_SERVER_MOUNT, api)
app.use('/dashboard', dashboard);
app.use(require('./controllers'))
parseServer.listen(process.env.PORT)

On production obviously the http->https is handled upstream by NGINX so providing certs to Express is unnecessary.

Shoutout to this stackoverflow thread for the breakthrough. Go there to see more of the why/how.

If there's a way to set strictSSL: false or similar on the ParseServer class that'd probably be better but I couldn't find one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants