Websocket error on HTTP Operation

Hey guys !

I’m building a web interface to manage my LXD containers. I use the lxd-node library to make my requests.

I can get my hosts and containers, stop, start or restart them but when it comes to sending commands, it doesn’t work.

I know that the node-lxd project is no longer maintained and I hesitate to create my requests directly by querying the LXD API but I would still like your feedback :

This is my function to send a command, I took the same example as in the official documentation, I just retrieve my container with an external function (which is working) :

public async execute(
    host: HostDto,
    container: ContainerDto,
    command: CmdDto,
  ) {
    let target = await this.getContainer(host, container);

    target.exec(['sleep', '5'], (err, process) => {
      if (err != null) {
        console.error(err);
        return;
      }

      process.on('close', () => {
        console.log('process closed');
      });
    });
  }

Unfortunately, my server is saying :

Error: unexpected server response (400)
    at ClientRequest.response (D:\Programation\Nasticot\NAS-SERVER\project\node_modules\ws-unix\lib\WebSocket.js:704:15)

And this part of the Websocket library is the following :

if (!self.emit('unexpected-response', req, res)) {
    error = new Error('unexpected server response (' + res.statusCode + ')');
    req.abort();
    self.emit('error', error);
 }

I probably miss something … If anyone has an idea, it would be very appreciated !

Thank you :slight_smile:

See if you can’t get the body of that error message, when we return 400, we may be telling you why.
Otherwise, make sure that you’re setting your content-type properly, that tends to be the most common issue.

Ok, I did a console.log() with the response body, that may help you :

IncomingMessage {
  _readableState:
   ReadableState {
     objectMode: false,
     highWaterMark: 16384,
     buffer: BufferList { head: null, tail: null, length: 0 },
     length: 0,
     pipes: null,
     pipesCount: 0,
     flowing: null,
     ended: false,
     endEmitted: false,
     reading: false,
     sync: true,
     needReadable: false,
     emittedReadable: false,
     readableListening: false,
     resumeScheduled: false,
     paused: true,
     emitClose: true,
     destroyed: false,
     defaultEncoding: 'utf8',
     awaitDrain: 0,
     readingMore: true,
     decoder: null,
     encoding: null },
  readable: true,
  _events: [Object: null prototype] { end: [Function: responseOnEnd] },
  _eventsCount: 1,
  _maxListeners: undefined,
  socket:
   Socket {
     connecting: false,
     _hadError: false,
     _handle:
      TCP {
        reading: true,
        onread: [Function: onStreamRead],
        onconnection: null,
        [Symbol(owner)]: [Circular] },
     _parent: null,
     _host: null,
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: false,
        endEmitted: false,
        reading: false,
        sync: false,
        needReadable: true,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        paused: false,
        emitClose: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: true,
     _events:
      [Object: null prototype] {
        end: [Array],
        free: [Function: onFree],
        close: [Array],
        agentRemove: [Function: onRemove],
        drain: [Function: ondrain],
        error: [Function: socketErrorListener],
        data: [Function: socketOnData] },
     _eventsCount: 7,
     _maxListeners: undefined,
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: false,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: false,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: false,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 0,
        prefinished: false,
        errorEmitted: false,
        emitClose: false,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: true,
     allowHalfOpen: false,
     _sockname: null,
     _pendingData: null,
     _pendingEncoding: '',
     server: null,
     _server: null,
     parser:
      HTTPParser {
        '0': [Function: parserOnHeaders],
        '1': [Function: parserOnHeadersComplete],
        '2': [Function: parserOnBody],
        '3': [Function: parserOnMessageComplete],
        '4': null,
        _headers: [],
        _url: '',
        socket: [Circular],
        incoming: [Circular],
        outgoing: [ClientRequest],
        maxHeaderPairs: 2000,
        _consumed: false,
        onIncoming: [Function: parserOnIncomingClient],
        [Symbol(isReused)]: true },
     _httpMessage:
      ClientRequest {
        _events: [Object],
        _eventsCount: 3,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: false,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [Circular],
        connection: [Circular],
        _header:
         'GET /1.0/operations/b5e7bfb9-fc1d-4769-87b2-1fb776a39190/websocket?secret=714053591c2a30534cbbec6cd97707c8b751d643fa2e0a06c9167249c86a5ff2 HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nHost: 192.168.0.12:8443\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: MTMtMTYwOTE0MzU3Mjk5Mw==\r\nSec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Agent],
        socketPath: undefined,
        timeout: undefined,
        method: 'GET',
        path:
         '/1.0/operations/b5e7bfb9-fc1d-4769-87b2-1fb776a39190/websocket?secret=714053591c2a30534cbbec6cd97707c8b751d643fa2e0a06c9167249c86a5ff2',
        _ended: false,
        res: [Circular],
        aborted: undefined,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: [HTTPParser],
        maxHeadersCount: null,
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object] },
     [Symbol(asyncId)]: 356,
     [Symbol(lastWriteQueueSize)]: 0,
     [Symbol(timeout)]: null,
     [Symbol(kBytesRead)]: 0,
     [Symbol(kBytesWritten)]: 0 },
  connection:
   Socket {
     connecting: false,
     _hadError: false,
     _handle:
      TCP {
        reading: true,
        onread: [Function: onStreamRead],
        onconnection: null,
        [Symbol(owner)]: [Circular] },
     _parent: null,
     _host: null,
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: false,
        endEmitted: false,
        reading: false,
        sync: false,
        needReadable: true,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        paused: false,
        emitClose: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: true,
     _events:
      [Object: null prototype] {
        end: [Array],
        free: [Function: onFree],
        close: [Array],
        agentRemove: [Function: onRemove],
        drain: [Function: ondrain],
        error: [Function: socketErrorListener],
        data: [Function: socketOnData] },
     _eventsCount: 7,
     _maxListeners: undefined,
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: false,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: false,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: false,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 0,
        prefinished: false,
        errorEmitted: false,
        emitClose: false,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: true,
     allowHalfOpen: false,
     _sockname: null,
     _pendingData: null,
     _pendingEncoding: '',
     server: null,
     _server: null,
     parser:
      HTTPParser {
        '0': [Function: parserOnHeaders],
        '1': [Function: parserOnHeadersComplete],
        '2': [Function: parserOnBody],
        '3': [Function: parserOnMessageComplete],
        '4': null,
        _headers: [],
        _url: '',
        socket: [Circular],
        incoming: [Circular],
        outgoing: [ClientRequest],
        maxHeaderPairs: 2000,
        _consumed: false,
        onIncoming: [Function: parserOnIncomingClient],
        [Symbol(isReused)]: true },
     _httpMessage:
      ClientRequest {
        _events: [Object],
        _eventsCount: 3,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: false,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [Circular],
        connection: [Circular],
        _header:
         'GET /1.0/operations/b5e7bfb9-fc1d-4769-87b2-1fb776a39190/websocket?secret=714053591c2a30534cbbec6cd97707c8b751d643fa2e0a06c9167249c86a5ff2 HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nHost: 192.168.0.12:8443\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: MTMtMTYwOTE0MzU3Mjk5Mw==\r\nSec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Agent],
        socketPath: undefined,
        timeout: undefined,
        method: 'GET',
        path:
         '/1.0/operations/b5e7bfb9-fc1d-4769-87b2-1fb776a39190/websocket?secret=714053591c2a30534cbbec6cd97707c8b751d643fa2e0a06c9167249c86a5ff2',
        _ended: false,
        res: [Circular],
        aborted: undefined,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: [HTTPParser],
        maxHeadersCount: null,
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object] },
     [Symbol(asyncId)]: 356,
     [Symbol(lastWriteQueueSize)]: 0,
     [Symbol(timeout)]: null,
     [Symbol(kBytesRead)]: 0,
     [Symbol(kBytesWritten)]: 0 },
  httpVersionMajor: 1,
  httpVersionMinor: 0,
  httpVersion: '1.0',
  complete: false,
  headers: {},
  rawHeaders: [],
  trailers: {},
  rawTrailers: [],
  aborted: false,
  upgrade: false,
  url: '',
  method: null,
  statusCode: 400,
  statusMessage: 'Bad Request',
  client:
   Socket {
     connecting: false,
     _hadError: false,
     _handle:
      TCP {
        reading: true,
        onread: [Function: onStreamRead],
        onconnection: null,
        [Symbol(owner)]: [Circular] },
     _parent: null,
     _host: null,
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: false,
        endEmitted: false,
        reading: false,
        sync: false,
        needReadable: true,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        paused: false,
        emitClose: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: true,
     _events:
      [Object: null prototype] {
        end: [Array],
        free: [Function: onFree],
        close: [Array],
        agentRemove: [Function: onRemove],
        drain: [Function: ondrain],
        error: [Function: socketErrorListener],
        data: [Function: socketOnData] },
     _eventsCount: 7,
     _maxListeners: undefined,
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: false,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: false,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: false,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 0,
        prefinished: false,
        errorEmitted: false,
        emitClose: false,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: true,
     allowHalfOpen: false,
     _sockname: null,
     _pendingData: null,
     _pendingEncoding: '',
     server: null,
     _server: null,
     parser:
      HTTPParser {
        '0': [Function: parserOnHeaders],
        '1': [Function: parserOnHeadersComplete],
        '2': [Function: parserOnBody],
        '3': [Function: parserOnMessageComplete],
        '4': null,
        _headers: [],
        _url: '',
        socket: [Circular],
        incoming: [Circular],
        outgoing: [ClientRequest],
        maxHeaderPairs: 2000,
        _consumed: false,
        onIncoming: [Function: parserOnIncomingClient],
        [Symbol(isReused)]: true },
     _httpMessage:
      ClientRequest {
        _events: [Object],
        _eventsCount: 3,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: false,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [Circular],
        connection: [Circular],
        _header:
         'GET /1.0/operations/b5e7bfb9-fc1d-4769-87b2-1fb776a39190/websocket?secret=714053591c2a30534cbbec6cd97707c8b751d643fa2e0a06c9167249c86a5ff2 HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nHost: 192.168.0.12:8443\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: MTMtMTYwOTE0MzU3Mjk5Mw==\r\nSec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Agent],
        socketPath: undefined,
        timeout: undefined,
        method: 'GET',
        path:
         '/1.0/operations/b5e7bfb9-fc1d-4769-87b2-1fb776a39190/websocket?secret=714053591c2a30534cbbec6cd97707c8b751d643fa2e0a06c9167249c86a5ff2',
        _ended: false,
        res: [Circular],
        aborted: undefined,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: [HTTPParser],
        maxHeadersCount: null,
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object] },
     [Symbol(asyncId)]: 356,
     [Symbol(lastWriteQueueSize)]: 0,
     [Symbol(timeout)]: null,
     [Symbol(kBytesRead)]: 0,
     [Symbol(kBytesWritten)]: 0 },
  _consuming: false,
  _dumped: false,
  req:
   ClientRequest {
     _events:
      [Object: null prototype] {
        error: [Function: onerror],
        upgrade: [Function],
        prefinish: [Function: requestOnPrefinish] },
     _eventsCount: 3,
     _maxListeners: undefined,
     output: [],
     outputEncodings: [],
     outputCallbacks: [],
     outputSize: 0,
     writable: true,
     _last: true,
     chunkedEncoding: false,
     shouldKeepAlive: false,
     useChunkedEncodingByDefault: false,
     sendDate: false,
     _removedConnection: false,
     _removedContLen: false,
     _removedTE: false,
     _contentLength: 0,
     _hasBody: true,
     _trailer: '',
     finished: true,
     _headerSent: true,
     socket:
      Socket {
        connecting: false,
        _hadError: false,
        _handle: [TCP],
        _parent: null,
        _host: null,
        _readableState: [ReadableState],
        readable: true,
        _events: [Object],
        _eventsCount: 7,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: true,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        parser: [HTTPParser],
        _httpMessage: [Circular],
        [Symbol(asyncId)]: 356,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0 },
     connection:
      Socket {
        connecting: false,
        _hadError: false,
        _handle: [TCP],
        _parent: null,
        _host: null,
        _readableState: [ReadableState],
        readable: true,
        _events: [Object],
        _eventsCount: 7,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: true,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        parser: [HTTPParser],
        _httpMessage: [Circular],
        [Symbol(asyncId)]: 356,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0 },
     _header:
      'GET /1.0/operations/b5e7bfb9-fc1d-4769-87b2-1fb776a39190/websocket?secret=714053591c2a30534cbbec6cd97707c8b751d643fa2e0a06c9167249c86a5ff2 HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nHost: 192.168.0.12:8443\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: MTMtMTYwOTE0MzU3Mjk5Mw==\r\nSec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n',
     _onPendingData: [Function: noopPendingOutput],
     agent:
      Agent {
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        defaultPort: 80,
        protocol: 'http:',
        options: [Object],
        requests: {},
        sockets: [Object],
        freeSockets: {},
        keepAliveMsecs: 1000,
        keepAlive: false,
        maxSockets: Infinity,
        maxFreeSockets: 256 },
     socketPath: undefined,
     timeout: undefined,
     method: 'GET',
     path:
      '/1.0/operations/b5e7bfb9-fc1d-4769-87b2-1fb776a39190/websocket?secret=714053591c2a30534cbbec6cd97707c8b751d643fa2e0a06c9167249c86a5ff2',
     _ended: false,
     res: [Circular],
     aborted: undefined,
     timeoutCb: null,
     upgradeOrConnect: false,
     parser:
      HTTPParser {
        '0': [Function: parserOnHeaders],
        '1': [Function: parserOnHeadersComplete],
        '2': [Function: parserOnBody],
        '3': [Function: parserOnMessageComplete],
        '4': null,
        _headers: [],
        _url: '',
        socket: [Socket],
        incoming: [Circular],
        outgoing: [Circular],
        maxHeaderPairs: 2000,
        _consumed: false,
        onIncoming: [Function: parserOnIncomingClient],
        [Symbol(isReused)]: true },
     maxHeadersCount: null,
     [Symbol(isCorked)]: false,
     [Symbol(outHeadersKey)]:
      [Object: null prototype] {
        connection: [Array],
        upgrade: [Array],
        host: [Array],
        'sec-websocket-version': [Array],
        'sec-websocket-key': [Array],
        'sec-websocket-extensions': [Array] } } }

I already had a look at it but didn’t find something relevant …

Thank you :slight_smile:

Still looking for a workaround.

Is there a place where LXD store REST API logs ? Don’t really know to solve this problem.

Here are some more informations about my infrastrcuture :

yanover@rasticit:/# lxd --version
4.9 

yanover@rasticit:/# lxc-ls
+------------+---------+--------------+--------------+----------------------+----------+
|    NAME    |  STATE  | DESCRIPTION  | ARCHITECTURE |         IPV4         | PROFILES |
+------------+---------+--------------+--------------+----------------------+----------+
| applicable | RUNNING | LAB          | armv7l       | 192.168.0.97 (eth0)  | rasticot |
+------------+---------+--------------+--------------+----------------------+----------+
| jakku      | RUNNING | NODE         | armv7l       | 192.168.0.57 (eth0)  | bridge   |
+------------+---------+--------------+--------------+----------------------+----------+
| mustafar   | RUNNING | GITLAB       | armv7l       | 192.168.0.58 (eth0)  | rasticot |
+------------+---------+--------------+--------------+----------------------+----------+
| najedha    | RUNNING | SAMBA        | armv7l       | 192.168.0.53 (eth0)  | rasticot |
+------------+---------+--------------+--------------+----------------------+----------+
| test       | RUNNING |              | armv7l       | 192.168.0.152 (eth0) | bridge   |
+------------+---------+--------------+--------------+----------------------+----------+
| tython     | RUNNING | TRANSMISSION | armv7l       | 192.168.0.55 (eth0)  | rasticot |
+------------+---------+--------------+--------------+----------------------+----------+

already searched answer under /var/snap/lxd/common/lxd but nothing interesting …

maybe a snap refresh could help ?

this is my version of the node-lxd module :

D:\Programation\Nasticot\NAS-SERVER\project>npm ls node-lxd
nas-server@0.0.1 D:\Programation\Nasticot\NAS-SERVER\project
`-- node-lxd@0.2.9 

… If someone could help me debugging this that would be awesome !

If your using the default method of initlizing a client by calling lxd() it wont work properly on modern LXD

Both theses lines point towards the old LXD socket location so it doesn’t work as expected (I get a 400 error)

If you replace /var/lib/lxd/ with /var/snap/lxd/common/lxd/ the following code works as expected

var lxd = require("node-lxd");

//NOTE cant do this, the library doesn't parse it properly
//var client = lxd("http://unix:/var/snap/lxd/common/lxd/unix.socket:/");
var client = lxd();

client.container("MY_INSTANCE", function(err, container){
    container.exec(["ls", "/etc"], function(err, process) {
      if (err != null) {
        console.error(err);
        return;
      }

      process.on("close", function() {
          console.log("process closed");
      });

      process.on("data", function(_, m){
          console.log("oo some output from my command");
          console.log(m);
      })
    });
});

As @Yanover pointed out in a DM they weren’t using the socket they were using an IP & certificate auth so my previous comment wont help them in this particular case.

node-lxd isnt my library but I did some digging and it would appear that its the use of ws:// instead of wss:// to connect to the LXD socket which breaks things

So we replace ws:// with wss:// but you will get an error about self signed certificates so you also have to modify

To prevent reject self signed certs, I.E;

var ws = new WebSocket(
        this._client._wsPath + '1.0/operations/' + this.id() +
        '/websocket?secret=' + secret, {
            rejectUnauthorized: false
        });

hmmm that’s weird, now I got 500 error with this code :

{
    let c = new ContainerDto({ name: 'jakku' });
    let h = new HostDto({ ip: '192.168.0.15' });

    let target = await this.getContainer(h, c);

    target.exec(['ls'], function(err, process) {
      if (err != null) {
        console.error(err);
        return;
      }
      process.on('data', function(_, m) {
        console.log('oo some output from my command');
        console.log(m);
      });
      process.on('close', function() {
        console.log('process closed');
      });
    });
  } 

I tried on different container and host, always the same result :

Error: unexpected server response (500)
    at ClientRequest.response (D:\Programation\Nasticot\NAS-SERVER\project\node_modules\ws-unix\lib\WebSocket.js:704:15)
    at Object.onceWrapper (events.js:277:13)
    at ClientRequest.emit (events.js:189:13)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:556:21)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
    at TLSSocket.socketOnData (_http_client.js:442:20)
    at TLSSocket.emit (events.js:189:13)
    at addChunk (_stream_readable.js:284:12)
    at readableAddChunk (_stream_readable.js:265:11)
    at TLSSocket.Readable.push (_stream_readable.js:220:10)

I also changed this line :
this._path = 'https://unix:/var/snap/lxd/common/lxd/unix.socket:/';

We have a server error now

[EDIT]
I just found this in the log, it seems to be a permission error :

lxc test 20210103193035.516 WARN     utils - utils.c:fix_stdio_permissions:1906 - Operation not permitted - Failed to chown standard I/O file descriptor 0 to uid -1 and gid 65534
lxc test 20210103193035.516 WARN     utils - utils.c:fix_stdio_permissions:1912 - Operation not permitted - Failed to chmod standard I/O file descriptor 0
lxc test 20210103193035.516 WARN     utils - utils.c:fix_stdio_permissions:1906 - Operation not permitted - Failed to chown standard I/O file descriptor 1 to uid -1 and gid 65534
lxc test 20210103193035.516 WARN     utils - utils.c:fix_stdio_permissions:1912 - Operation not permitted - Failed to chmod standard I/O file descriptor 1
lxc test 20210103193035.516 WARN     utils - utils.c:fix_stdio_permissions:1906 - Operation not permitted - Failed to chown standard I/O file descriptor 2 to uid -1 and gid 65534
lxc test 20210103193035.516 WARN     utils - utils.c:fix_stdio_permissions:1912 - Operation not permitted - Failed to chmod standard I/O file descriptor 2
lxc test 20210103193035.516 WARN     attach - attach.c:attach_child_main:882 - Failed to adjust stdio permissions

I thought that when you trigger lxd from the API with a valid certificat and password, it was executed with the same permission than when you do :

lxc exec containerName -- command

So with root privileged, isn’t that right ?

Thank you again guys !

In that case I have no idea, ive investigated the core library with as much time as I can;

If you follow my fix guide the library will work, outside of that the implication is that your code is wrong

Editing files in node_modules isn’t a long term solution anyway so unless you plan to learn the library & submit the fixes this isn’t the path you want to carry on down. Investigate the forks or the typescript library!

There are lots of web interfaces for LXD already you could turn to them for some inspiration!

I believe you did you best and I thank you for that !

I know that starting to edit module in nodes_modules is a short term solution.

I think I’m gonna build a new backend with Flask and pylxd. This lxd-node library should not longuer be proposed as long as it is not updated.

I already tried your great lxdMozaic app, liked it very much ! Great job :slight_smile:

Thank you again for you time !