IPFS API returns 404

Hello everyone!

I’m writing a POC which runs an IPFS node and also an instance of IPFS Cluster. I can successfully start the node and the cluster. The problem is that the IPFS API only returns 404 RPC endpoint doesn’t exist. I used the functions serveHTTPApi and serveHTTPGateway from the daemon source code. Both the API and Gateway starts up, it’s possible to see it in the open ports of my pc

main 14281 mypc 24u IPv4 0x9192403e3001e1dd 0t0 TCP *:4001 (LISTEN)
main 14281 mypc 26u IPv6 0x9192403e2ee8bd3d 0t0 TCP *:4001 (LISTEN)
main 14281 mypc 43u IPv4 0x9192403e2e8e856d 0t0 TCP localhost:5001 (LISTEN)
main 14281 mypc 45u IPv4 0x9192403e2ec91655 0t0 TCP localhost:8080 (LISTEN)

IPFS node is running API server listening on /ip4/ WebUI: Gateway (readonly) server listening on /ip4/

I’m also able to access the WebUI but with the message Failed to connect to the API. Using curl returns 404 no any endpoint too.

The cluster throws this errors:

2020-06-26T20:30:19.908+0100 ERROR ipfshttp IPFS request unsuccessful (repo/stat?size-only=true). Code 404. Body: 404 page not found

2020-06-26T20:30:19.908+0100 ERROR p2p-gorpc IPFS request unsuccessful (repo/stat?size-only=true). Code 404. Body: 404 page not found

2020-06-26T20:30:19.908+0100 ERROR diskinfo IPFS request unsuccessful (repo/stat?size-only=true). Code 404. Body: 404 page not found

Things I already tried:
What says in WebUI to add to the HTTPHeaders “Access-Control-Allow-Methods” and “Access-Control-Allow-Origin”
Set Gateway.Writable: true

Bare in mind that if I start the ipfs via ipfs daemon my cluster can easily connect to it. So it’s only a problem in my own ipfs node.

If someone already suffered from this or can give a hint about what might be the problem I would really appreciate. Thank you!

Package versions:
github.com/ipfs/go-ipfs v0.5.0
github.com/ipfs/go-ipfs-config v0.5.3
github.com/ipfs/ipfs-cluster v0.13.0

Do you mean you are running a custom build of the ipfs daemon?

Sorry for the late response toke the weekend off.

Yes I’m using the go-ipfs library to initialize my own node based on this example and a custom build of the ipfs-cluster in the same code. Basically I first start the IPFS node and then if succeed starts the ipfs cluster and connects to
To initialize the IPFS node API I toke a look at the IPFS daemon source code and used both the serveHTTPApi and serveHTTPGateway functions to expose the API and Gateway Ports. But I guess I might be missing something because indeed the ports were open, but the API does not expose any endpoint.

Well, your API 404-ing means request handlers might be missing. I am not sure what needs to be done to run the gateway by hand (doesn’t the example does it by itself?). If you are binding both ipfs and ipfs-cluster in a single binary, you could skip using the http api altogether though and add a new connector implementation directly that uses the ipfs core API directly (related https://github.com/textileio/go-textile/pull/831/files#diff-5d87e68af33532d3c963b1dc695da064R1)

I ran the example code and saw that it only opened the port 4001 but not the API (5001) and Gateway (8080) ones so I guess not.

That might be really handy! Tomorrow I will give it a try and will leave feedback when done. Thank you a lot

@hector Just managed to make it work with a new connector. Only needed to rewrite a little bit of the code of the Textile PR you sended. Thank you a lot

1 Like

@hector I don’t know if I just found a bug or not but wanted you to take a quick look to see if I really should open an issue on Git.

I used a custom connector as I said before, and everything seemed to be working until I tried to bootstrap the peer to another one. It would bootstrap and after 5 seconds It would throw a panic error:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x50 pc=0x4f44886]
goroutine 22381 [running]:
github.com/ipfs/ipfs-cluster.(*Cluster).Peers(0xc0006fa000, 0x5810ba0, 0xc0039d0120, 0x0, 0x0, 0x0)
/Users/mosanoteam/go/pkg/mod/github.com/ipfs/ipfs-cluster@v0.13.0/cluster.go:1579 +0x136
main.startCluster.func1(0x5810ba0, 0xc0039d0120, 0x0, 0x0, 0x2f40)
/Users/mosanoteam/go/src/github.com/PZenha/poc-ipfs-cluster/main.go:497 +0x3e
main.(*Connector).ConnectSwarms(0xc000e21ca0, 0x5810ba0, 0xc0039d0120, 0x0, 0x40624d1)
/Users/mosanoteam/go/src/github.com/PZenha/poc-ipfs-cluster/connector.go:100 +0x5c
/Users/mosanoteam/go/pkg/mod/github.com/ipfs/ipfs-cluster@v0.13.0/cluster.go:974 +0x4b
created by time.goFunc
/usr/local/Cellar/go/1.13.7/libexec/src/time/sleep.go:168 +0x44
exit status 2

The problem seems to be from the function
func (c *Cluster) Peers(ctx context.Context) []*api.ID {...}

It was originally called like this:

connector, err := NewConnector(GetNode(), func(ctx context.Context) []*capi.ID {
return c.Peers(ctx)

And instead of using the Peers method from the Cluster struct I used the Peers function from the Rest API as a work around and works fine.
Do you think this might be a problem from the lib worth of opening an issue?

Let’s see. In IPFS cluster, IPFS is a separate program with its own libp2p host and cluster has its own libp2p host as well.

In the Textile approach, the libp2p host is shared.

The connector has a SwarmPeers function which should return IPFS peers. This is used by cluster to auto-connect IPFS daemons from every peer 5 seconds or so after boot (where you get the error) (I think), via ConnectSwarms.

In the Textile version, cluster peers == ipfs peers because the libp2p host is shared after all, so they pass a function so that they can get the cluster peers from inside the SwarmPeers function.

You replaced this with Peers from restapi and somehow this ends up calling c.consensus.Peers() and somehow used the peers function from the rest api (peerListHandler?).

The panic shows that something is nil (c.consensus?). I am not sure how that can happen though at that place exactly. What consensus are you using?

Thing is, you are bootstrapping the consensus layer and probably, before being finished with it, you are also requesting Peers() from that same layer (via c.Peers()) so it might be a chicken-egg problem. You may try to make ConnectSwarms() a no-op and work your way from there. It’s not clear to me what exactly is nil that causes the panic though, given the trace.