Fly NodeJs App keeps throwing 500 server error when request body is multipart/form data

Here is what the logs are saying:

cdg [info] Error: connect ENETUNREACH <ip-address>
cdg [info] at TCPConnectWrap.afterConnect [as oncomplete]

Hi,

Does the app work locally when you send it that same request?

Only most issues with multipart requests are down to the app/code, rather than the platform. Since you will probably be using Express. And that comes with Express body-parser middleware for parsing request bodies. It doesn’t support multipart. Many people use multer for that: multer - npm So if you haven’t already, you may need to add multer as a dependency.

That would be the first thing I’d look at.

1 Like

Thank you very much.
I’m very much aware of this.
You see, the concern here is that this same endpoint works on my local machine.

But it fails on fly.io server

Ah. Ok.

In which case that suggests a network issue. Is the redacted IP address one of yours (like that app’s IP, or another IP within Fly)? Or is it for an external service you are trying to connect to (AWS, GCP etc)? Since why it can’t resolve/connect would depend on what exactly you are trying to do.

Sometimes it will be an IPv4 vs IPv6 issue. Some networks may not support/resolve IPv6 but Fly uses IPv6 internally for the private network your app lives in.

Else sometimes I’ve had issues with DNS when using Alpine as the base image for node apps. Not sure why but sometimes if you have a Dockerfile that is based on Alpine, it can be as simple as switching the first line to be e.g Ubuntu or one of the others.

All guesses I’m afraid.

the app at some point connects to another app hosted on Fly. But this particular endpoint has no connection with this other app.

This endpoint basically uploads pictures

// Router

router.put("/profilePicture", JWTAuth, isAdmin, upload.single("image"), async (req, res) => {
    try {
        if (!req.file) {
            return handleResponse(400, "no image provided", null, res);
        }

        const response = await adminControllers.updateProfilePicture({
            image: req.file.location,
            admin: req.user,
        });

        return res.status(response.code).json(response);
    } catch (e) {
        logger.error("🔥 error: %o", e);
        Sentry.captureException(e);
        return handleResponse(500, "failed to update profile picture", null, res);
    }
});

So this endpoint doesn’t connect to the second Fly app but most likely will connect to the database.
If it is then the ip address of the mongo database, why doesn’t it reject other kinds of requests. It only rejects requests with multipart/form bodies

Hi,

Well first, if you do have a Dockerfile, it is certainly worth trying to change the base image, just to rule that out. Can’t hurt if your app does use a base of alpine. As I’ve found that helps in the past.

Else it’s not that, clearly. What’s interesting is that it seems from your first log output that your “catch” is not being triggered. Since if it was, your logs should show additional lines (and so would Sentry). And indeed return a different error message. So that suggests to me that it may be part of the middleware that is failing. I see you have multiple middleware and so personally I’d look into those. Sometimes it is a case of adding console.log lines (or logger.error) throughout, just to see where it is getting to before it then fails. At least ruling out which bits do work. And when you run fly logs you would see it getting to line X and failing at line Y.

1 Like

Thanks alot for your assistance @greg.

I’ve been able to resolve the issue.
The problem occurred because the AWS Secret and Access Key wasn’t imported correctly from the env file.
So it was the AWS SDK throwing the connection error.

Thanks again

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.