Private Preview
This feature is in private preview: it's not ready for production use, and it may be briefly unavailable as we deploy updates. To get access, sign up here.
Authentication errors
403 InvalidAccessKeyId
The Access Key ID is wrong, missing, or the credential has been revoked.
Fix: Check that AWS_ACCESS_KEY_ID is set to the token_id from the credential response, not token_id_short. See Authentication for the correct field mapping. If you no longer have it, revoke the credential and create a new one.
403 SignatureDoesNotMatch
The Secret Access Key is wrong.
Fix: Check that AWS_SECRET_ACCESS_KEY is set to the s3_secret_access_key field from the credential response. This is the 64-character hex string, not the api_token. Both are returned only once at creation. If you no longer have the s3_secret_access_key, revoke the credential and create a new one.
403 AccessDenied: missing scope
The credential does not have the required scope for the operation.
Fix: Check which scopes the credential was created with:
storage:readallows GetObject, HeadObject, ListBuckets, and ListObjectsV2storage:writeallows all reads plus PutObject, DeleteObject, CreateBucket, and DeleteBucket
To add write access, create a new credential with storage:write. You can't add scopes to an existing credential.
403 AccessDenied: wrong branch
The credential was issued on a branch that is not an ancestor of the branch you are making requests against.
Fix: Use a credential issued on the target branch or one of its ancestor branches. See Authentication for how branch binding works.
SDK configuration errors
Requests go to AWS instead of Neon
If you forget to set the custom endpoint, the SDK will route requests to AWS S3 and fail with a credentials error or bucket-not-found.
Fix: Always set the endpoint (JavaScript) or endpoint_url (Python/CLI) to your branch storage host:
const client = new S3Client({
endpoint: process.env.AWS_ENDPOINT_URL_S3,
// ...
});NoSuchBucketon every request
Without forcePathStyle: true, the SDK treats the bucket name as a subdomain instead of a path segment.
Fix: Add forcePathStyle: true to your S3Client configuration:
const client = new S3Client({
forcePathStyle: true, // required for Neon Storage
// ...
});Without this, the AWS SDK for JavaScript uses virtual-hosted-style addressing (my-bucket.storage.example.com/key) which Neon Storage doesn't support.
SigV2 errors
If you see signature-related errors mentioning AWS2 or AWSAccessKeyId, your client is using the older AWS Signature Version 2.
Fix: Use AWS Signature Version 4 (SigV4). The AWS SDK v3 for JavaScript and boto3 use SigV4 by default. If you're using an older SDK or a custom HTTP client, update it or configure it to use SigV4 explicitly.
Access level errors
Anonymous GET returns403 AccessDenied
The bucket's access level is private (the default), which requires authentication for all reads.
Fix: If the bucket should allow public reads, set its access level to public_read using the Neon Console or API. See Access levels.
note
You cannot change access level via the S3 API. PutBucketAcl returns 501 Not Implemented.
S3 operation errors
501 Not Implemented
You are calling an S3 operation that Neon Storage does not support.
Common causes:
PutBucketAclorPutBucketPolicy: use the Neon Console or API to set bucket access level insteadPutBucketNotificationConfiguration: event notifications are not supportedPutBucketLogging: server-side access logging is not supported
See S3 compatibility for the full list of unsupported operations.
Lifecycle rules not running
PutBucketLifecycle succeeds and the configuration is stored, but expiration and transition rules do not execute.
Status: Lifecycle enforcement isn't available in Private Preview. The API accepts and echoes the configuration so tools that read lifecycle rules will work, but the rules have no effect.
Connection and performance errors
503 Service Unavailable(SlowDown)
The request exceeded the per-IP or per-tenant rate limit. The S3 error code is SlowDown. This is a rate limit signal, not a server error. The storage service is healthy.
Fix: Implement exponential backoff and retry. Don't treat SlowDown as a fatal error. The response may include a Retry-After header indicating how long to wait. AWS SDKs handle this automatically when retry logic is enabled.
Large downloads timing out mid-stream
The connection drops during a large object download.
Fix: Use range requests to download large objects in chunks:
// Download in 10 MiB chunks
const chunkSize = 10 * 1024 * 1024;
let start = 0;
while (true) {
const response = await client.send(new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'large-file.zip',
Range: `bytes=${start}-${start + chunkSize - 1}`,
}));
// process response.Body
if (response.ContentRange?.endsWith(response.ContentLength?.toString() ?? '')) break;
start += chunkSize;
}Need help?
Join our Discord Server to ask questions or see what others are doing with Neon. For paid plan support options, see Support.








