# Errors and troubleshooting

> Diagnose HTTP proxy errors and SOCKS5 handshake or tunnel failures.
>
> Web page: https://ports.io/docs/reference/troubleshooting/
> Documentation index: https://ports.io/llms.txt

Identify the proxy protocol and the stage that failed. HTTP proxy setup can return an HTTP status, JSON error code, and `Proxy-Status` header. SOCKS5 setup returns handshake statuses and binary reply codes. A destination response received after successful tunnel setup belongs to the destination.

## HTTP proxy error reference

| Status | Error code | Meaning | First action |
| --- | --- | --- | --- |
| `400` | `invalid_request` | Malformed proxy request or invalid hostname/port | Correct the request format |
| `400` | `ip_target_unsupported` | The destination is an IP address | Use a destination hostname |
| `501` | `method_not_supported` | The HTTP proxy request is neither CONNECT nor absolute-form forwarding | Use the HTTP client's proxy settings |
| `407` | `invalid_credentials` | Proxy credentials or routing username are invalid | Check the username and complete key secret |
| `407` | `key_expired` | The key has expired | Create a replacement key |
| `407` | `key_revoked` | The key has been revoked | Use a valid replacement key |
| `407` | `account_disabled` | The workspace is disabled | Check its status in the console and contact support |
| `502` | `no_exit_available` | No eligible exit matches the requested route | Check filters and location availability |
| `503` | `routing_unavailable` | Route selection could not complete | Retry a safe request later with bounded backoff |
| `502` | `exit_unreachable` | The selected exit could not be reached | Check session policy; retry a safe request with backoff |
| `504` | `exit_timeout` | The selected exit did not respond in time | Reduce immediate retries and check destination access |
| `502` | `target_dns_failed` | The exit could not resolve the hostname to permitted addresses | Check the hostname and destination policy |
| `502` | `target_unreachable` | The exit could not connect to the destination | Check the destination hostname, port, and availability |
| `502` | `target_closed` | An HTTP forward destination closed without a response | Retry only if the request can safely be repeated |

Admission limits can also close a connection before setup without a structured HTTP response. A connection can close before parsing or when its initial request misses the setup deadline.

## HTTP error shape

Structured setup failures use this shape:

```http
HTTP/1.1 502 Bad Gateway
Proxy-Status: ports.io; error=destination_unavailable; details="target_unreachable"
Content-Type: application/json

{"error":{"code":"target_unreachable","message":"the exit could not connect to the target"}}
```

Use `error.code` for machine classification. The `Proxy-Status` header's `details` field carries the same code, which can help when an HTTP library exposes a failed CONNECT response's headers but not its body. Do not depend on `error.message` as a stable programmatic identifier. A `407` also includes `Proxy-Authenticate: Basic`.

## SOCKS5 failures

SOCKS5 does not return HTTP `407` or a JSON error body during setup. First determine whether method negotiation, username/password authentication, or the CONNECT request failed.

| Stage | Value | Meaning | First action |
| --- | --- | --- | --- |
| Method negotiation | `0xff` | No acceptable authentication method | Enable SOCKS5 username/password authentication |
| Username/password authentication | `0x01` | Authentication failed | Check routing username, full key, expiration, revocation, and workspace status |

After successful authentication, these CONNECT reply codes can occur:

| Reply code | Meaning in this gateway | First action |
| --- | --- | --- |
| `0x01` | General failure, including an invalid request, unavailable routing, or an unreachable exit | Check request format and route; retry transient failures with backoff |
| `0x02` | Destination IP address rejected by policy | Enable remote DNS and use a destination hostname |
| `0x04` | Destination DNS or connection failure | Check hostname, port, reachability, and destination restrictions |
| `0x06` | Selected exit timed out | Retry a safe request later with backoff |
| `0x07` | Command not supported | Use CONNECT; BIND and UDP ASSOCIATE are unsupported |
| `0x08` | Unknown address type | Use a SOCKS5 client that sends a domain-name address |

SOCKS replies group several internal failure causes. Authentication failure does not distinguish an invalid key from an expired or revoked one. Record the client error and the stage instead of expecting the HTTP error catalog's JSON codes.

For curl or Python Requests, use `socks5h://` to send the destination hostname. Their `socks5://` mode resolves locally and sends an IP address, which receives `0x02`. A destination URL containing an IP literal also fails with remote DNS enabled. See [Protocols and limits](https://ports.io/docs/reference/protocols-and-limits.md#destinations).

## Resolve authentication failures

1. Use a valid routing username such as `v1_rotate`; account IDs and key display names do not belong in it.
2. Send the complete proxy key secret as the password. Remove copied whitespace and newlines.
3. Configure proxy Basic authentication for HTTP, or username/password authentication for SOCKS5. Do not use destination authentication or a bearer token.
4. Check whether the key has expired or been revoked, whether its workspace is enabled, and whether it belongs to the assigned environment.

If an unchanged key fails across valid usernames, investigate the workspace and service status before creating more keys. Repeatedly creating keys will not resolve a service outage.

## Check destination and session failures

For `no_exit_available`, look for filters that contradict each other or remove every permitted country. A recognized country code can still have no active exit.

For destination DNS or connection failures, check that the hostname and port are correct and reachable from a public network. Private and special-purpose destinations are blocked by default. A destination may also refuse connections or deny requests based on its own policy.

For a session, preserve the strategy and filter policy associated with the ID. Choose a new ID when changing either. Fixed sessions do not fail over an unreachable bound exit. See [Sessions and rotation](https://ports.io/docs/reference/sessions.md).

## Handle admission failures and connection drops

Reduce parallel connections and avoid a burst of immediate retries. Proxy setup can be rejected by source-IP, concurrency, or connection-rate limits, unavailable routing, or destination policy.

After HTTP `200 Connection Established` or a successful SOCKS5 CONNECT reply, the tunnel can still close because of a network failure, an origin or client disconnect, or the idle/lifetime deadline. Established traffic is not replayed by the proxy. Retry only when your application can safely repeat the operation; use capped exponential backoff and jitter for transient failures.

## Reproduce with a minimal client

Use your assigned endpoint, an existing valid key, a plain routing username, and a destination hostname:

```sh
curl --proxy "$PORTS_PROXY_URL" \
  --proxy-user "v1_rotate:$PORTS_PROXY_KEY" \
  --connect-timeout 15 \
  --max-time 30 \
  https://example.com/
```

For SOCKS5, set `PORTS_PROXY_URL` to the assigned `socks5h://` endpoint with its port. For HTTP proxying, use the assigned `http://` or `https://` endpoint. A standard `socks5h://` connection cannot be sent directly to a TLS-only proxy port.

Keep verbose traces private: they can include proxy or destination credentials. Remove credentials before sharing any diagnostic output.

## Information to include in a support report

- Timestamp and timezone.
- Proxy protocol, endpoint, and client/library version.
- Routing username, destination hostname and port, and concurrency level.
- Failure stage: negotiation, authentication, tunnel setup, or destination response.
- HTTP proxy status/error code, or SOCKS handshake status/reply code when available.
- Key ID or visible suffix, without the full secret.
- Whether a minimal request reproduces the problem and whether other destinations work.

The customer-facing error response currently has no documented request-ID field. Record your own request correlation ID when troubleshooting application batches.
