"Server responded HTTP" Error

Hi. I started neo4j:enterprise on a k8s container and I mapped port 7687 to 80, so when I want to connect to neo4j server I should connect to this address: bolt://db.site.com:80 with default username and password.
I can connect to server by neo4j desktop client but when I want to do that in my JavaScript (node.js) app, I can't and driver will throw this error:
Neo4jError: Server responded HTTP. Make sure you are not trying to connect to the http endpoint (HTTP defaults to port 7474 whereas BOLT defaults to port 7687)
when I open db.site.com in my browser it will say: not a WebSocket handshake request: missing upgrade
I can't use default port of bolt (7687) and I have to map it to 80 port.
Please tell me how desktop client can connect but drivers (especially JavaScript driver) can't and how can I fix this problem?

1 Like

I am having the exact same issue. Looking at the source it seems that the actual response from the server is literally "http" in unicode, which makes sense as that's usually what HTTP servers start off with responding with "HTTP/2 ....."

WSS straight to my server seems to work, browser/neo4j desktop works. Node Driver doesn't....wonder if we can force node to use a WSS client, there's something wonky in the node handling for protocol negotiation it seems.

Looking into the code it seems as if its creating a channel in the node driver that uses a very different underlying transport (the net module vs whatever provided by the browser JS env) than you'd get in the browser (that just seems to be opening up a WSS connection), which follows the browser Channel path when the driver is running in the browser that seems to trunk the BOLT binary data over a WSS connection, in node it doesn't do that, it goes straight to the net package (sockets), so it definitely isn't happy about having to speak HTTP is sounds like, because it seems that the service running on 7687 (bolt server) decides to start speaking HTTP when/if it gets an HTTP request, but otherwise it's sockets and does protocol version detection.

SO, if your client is expecting that BOLT conversation but gets HTTP b/c nginx ingress in the middle is forcing that conversation in HTTP, the client is gonna get HTTP back.

I think the only solutions are to remove nginx ingress from the middle of this all or configure nginx (via tcp-services or something) to let that port fly TCP only (or just not assume its HTTP off the bat).

1 Like