Search code examples
node.jsgoogle-app-enginegoogle-cloud-platformgoogle-cloud-sql

Cloud SQL is throwing ETIMEDOUT error when queried from node js application deployed in google cloud app engine


I am working on a node js application with cloud sql as the database. I developed the application in my local host and deployed to google cloud app engine. In app engine, I am getting the below mentioned error. Note: I verified that database credentials are correct. Tried many things including increasing connection timeout, but same error persists.

A { Error: connect ETIMEDOUT at Connection._handleConnectTimeout (/app/node_modules/mysql/lib/Connection.js:419:13) at Object.onceWrapper (events.js:313:30) at emitNone (events.js:106:13) at Socket.emit (events.js:208:7) at Socket._onTimeout (net.js:407:8) at ontimeout (timers.js:475:11) at tryOnTimeout (timers.js:310:5) at Timer.listOnTimeout (timers.js:270:5)

A --------------------

A at Protocol._enqueue (/app/node_modules/mysql/lib/protocol/Protocol.js:145:48)

A at Protocol.handshake (/app/node_modules/mysql/lib/protocol/Protocol.js:52:23)

A at Connection.connect (/app/node_modules/mysql/lib/Connection.js:130:18)

A at Connection._implyConnect (/app/node_modules/mysql/lib/Connection.js:461:10)

A at Connection.query (/app/node_modules/mysql/lib/Connection.js:206:8)

A at Object. (/app/code/nodejs/app.js:27:9)

A at Module._compile (module.js:643:30)

A at Object.Module._extensions..js (module.js:654:10)

A at Module.load (module.js:556:32)

A at tryModuleLoad (module.js:499:12)

A errorno: 'ETIMEDOUT',

A code: 'ETIMEDOUT',

A syscall: 'connect',

A fatal: true }


Solution

  • socketPath should be set to "/cloudsql/{INSTANCE_CONNECTION_NAME}" to fix this issue (socketPath is not required for instance in local machine to work). There is no need to set host. Sample code snippet is given below

    const knex = connect();
    
    function connect () {
      const config = {
        user: process.env.SQL_USER,
        password: process.env.SQL_PASSWORD,
        database: process.env.SQL_DATABASE
      };
    
      if (process.env.INSTANCE_CONNECTION_NAME && process.env.NODE_ENV === 'production') {
        config.socketPath = `/cloudsql/${process.env.INSTANCE_CONNECTION_NAME}`;
      }
    
      // Connect to the database
      const knex = Knex({
        client: 'mysql',
        connection: config
      });
    
      return knex;
    }
    

    Reference: https://cloud.google.com/appengine/docs/flexible/nodejs/using-cloud-sql

    Additional points to note:

    1) Cloud SQL API should be enabled

    2) In app.yaml, cloud_sql_instances should be added in beta_settings section

    beta_settings:
      cloud_sql_instances: YOUR_INSTANCE_CONNECTION_NAME
    

    If this is not provided, it will generate an error (Error: connect ENOENT instance_name at Object._errnoException (util.js:1022:11) at _exceptionWithHostPort (util.js:1044:20) at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1182:14))