Proxy troubleshooting
Most proxy problems are one of a few causes: credentials, a destination allowlist, a client that cannot open TLS to the proxy, or an allowlist that is missing one of your IPs. Start with curl -v.
Docs preview: Fixedmark is not live yet. Endpoints are issued at launch, and these pages describe planned launch behavior. Anything marked planned may change. Join early access to get yours first.
X-Proxy-Error header on this page are planned launch behavior and may change. Connection logs in the dashboard show the destination, SNI, bytes, egress IP, and result for each connection, which answers most of these questions directly.Start with curl -v
curl -v shows the proxy handshake and the destination response separately. Look for the line after CONNECT.
curl -v --proxy "$FIXEDMARK_PROXY_URL" https://api.partner.example/v1/orders
# Proxy refused the tunnel:
# < HTTP/1.1 407 Proxy Authentication Required
# curl: (56) CONNECT tunnel failed, response 407
#
# Tunnel open, destination answered:
# < HTTP/1.1 200 Connection Established
# ...
# < HTTP/2 403407 Proxy Authentication Required
- The app ID or token is wrong, revoked, or from another app. Copy the full URL again from the dashboard.
- The token contains
@,:,/, or%and is not URL-encoded in the URL. - The variable has quotes or a trailing newline from a copy and paste.
- The client did not send credentials. Java's HttpClient disables Basic auth for tunnels by default. See the Java guide.
- Your plan's quota is used up. The response then carries
X-Proxy-Error: quota_exceeded. See quotas.
403: destination not allowed
When the proxy itself refuses the CONNECT, the token probably has a destination allowlist that does not include this host and port. Add the exact host and port, such as api.example.com:443, or use a token meant for that service.
The proxy also refuses some destinations for every customer: the SMTP ports 25, 465, and 587 unless enabled for your account after verification, and networks on abuse blocklists.
403 or rejection from the destination
If CONNECT returned 200, the proxy did its part. The destination rejected the request. Common causes:
- Only one IP of the pair is on the allowlist. Requests from the other fail. Add both.
- The allowlist change has not applied yet. Some banks and brokers take hours or have a cooldown between changes.
- The request did not use the proxy at all. Check with the IP endpoint.
- The API also checks something else, such as an API key, a client certificate, or a registered domain.
TLS errors when connecting to the proxy
The proxy endpoint on port 443 expects TLS first. A client that does not support https:// proxy URLs speaks plain HTTP to it, and you see errors such as wrong version number, socket hang up, EPROTO, or an immediate reset.
- Upgrade the client: curl 7.52+, urllib3 1.26+ for requests, httpx 0.28+, axios 1.16.1+, Go 1.10+, and Typhoeus for Ruby.
- aiohttp on Python 3.10 or older fails with
Cannot initialize a TLS-in-TLS connection. Use Python 3.11+. - Ruby's Net::HTTP fails with
SSL_connect ... unexpected messagefor HTTPS destinations. See the Ruby guide. - Certificate errors that name the proxy host usually mean a corporate TLS inspection box or an outdated CA bundle in the container image. Update
ca-certificates.
Timeouts
- Connect hangs, then times out. Firewalls drop packets from IPs they do not allow instead of refusing them. This is the usual symptom for databases and MongoDB Atlas. Allowlist both IPs.
- Slow first request. A cold start pays for TLS to the proxy and TLS to the destination. Reuse one client or agent so later requests skip both handshakes.
- Slow every request. The region may be far from the destination. Choose the region nearest the API you call.
- Set explicit connect and read timeouts in your client. Several defaults wait forever.
Connection resets
- Idle connections drop. The proxy closes idle connections after a timeout, planned at 5 minutes by default. Set pool idle timeouts lower, or enable TCP keepalive.
- A burst of resets, then recovery. A node failed or was replaced, and its IP moved. Open connections on it drop. Retry idempotent requests.
- Resets right after CONNECT. The destination closed the connection, often because the IP is not allowed.
DNS leaks and wrong IPs
With socks5://, curl, Python requests, and other clients resolve the host name locally and send an IP to the proxy. Your local resolver sees the lookup, and geo-DNS may return an address meant for your app's region. Use socks5h:// so the proxy resolves the name. HTTP CONNECT always sends the host name.
Private names such as db.internal do not resolve on the proxy. Use the public host name of the service.
Requests skip the proxy
NO_PROXYmatches the destination, often through a broad suffix such as.com.- Lowercase
https_proxyis set to a different value. Most tools prefer the lowercase variable when both exist. - The library ignores proxy variables. aiohttp needs
trust_env=True. Node's globalfetchneedsNODE_USE_ENV_PROXY=1or an undici dispatcher. - Go never proxies
localhostthroughProxyFromEnvironment.
429 and quotas
Quotas are soft. Planned behavior: you get usage alerts as you approach your plan's limit, and traffic continues for a margin past it. After that, the proxy answers with 429 or 407 and X-Proxy-Error: quota_exceeded. Per-app rate limits on requests per second and concurrent connections are also planned. See limits and quotas.
Platform guides
Frequently asked questions
What does 407 Proxy Authentication Required mean?
The proxy did not accept your credentials. The app ID or token is wrong, special characters in the token are not URL-encoded, or the client did not send credentials at all.
How do I tell a proxy error from a destination error?
Run curl -v through the proxy. If the CONNECT response is not 200, the proxy refused the connection. If CONNECT returns 200 and you then get a 403, the destination rejected you.
Why does my database connection time out through the proxy?
Usually the database firewall silently drops connections from an IP it does not allow. Allowlist both IPs in your pair. Also check that the host and port are in the token's destination allowlist.
Make it fixed.
Fixedmark is in early access. Join the list to get dedicated static IPs when your region opens.