Signature errors
Fix SignatureDoesNotMatch and other errors about the request signature.
This page helps when Zata answers 403 SignatureDoesNotMatch: the signature your tool sent does not match the one Zata calculates from the same request. It also covers presigned links that return 403.
On AWS these errors often mean a wrong region. Zata does not check the region name, so the region setting never causes a signature error here. Keep it at us-east-1 and look at the causes below.
Quick fixes
| You see | Most likely cause | Fix |
|---|---|---|
SignatureDoesNotMatch in every tool | The secret key is wrong: a missing character, or an extra space or line break from pasting | Enter the secret key again |
SignatureDoesNotMatch on every rclone command | rclone signs the Accept-Encoding header, which changes on the way to Zata | Set sign_accept_encoding = false (rclone v1.70+; update rclone if older) |
SignatureDoesNotMatch from a Go app (AWS SDK for Go v2) | Same as rclone | Leave Accept-Encoding out of the signature |
| Works on one network, fails on another (for example the office) | A proxy or security appliance changes the request | Bypass the proxy for Zata |
Only files with spaces, + or non-English characters fail | The tool encodes the name differently | Test the name with the AWS CLI |
s3cmd: 403 (SignatureDoesNotMatch) | host_bucket contains a bucket placeholder | Fix host_bucket |
403 when you upload with a presigned link | The Content-Type header differs from the one in the link | Send the same Content-Type |
InvalidAccessKeyId | The access key ID is wrong or from the other region — not a signature problem | See Wrong endpoint or region |
AWS CLI: argument of type 'NoneType' is not a container or iterable | The AWS CLI cannot display Zata's error | Run the command with --debug |
The secret key is wrong
A wrong access key ID gives InvalidAccessKeyId. A wrong secret key gives exactly SignatureDoesNotMatch. Usually a character is missing, or a space or line break was pasted with the key.
-
Check which keys the tool really uses. The AWS CLI shows the last four characters of each key and where it found them (environment variable, credentials file or config file):
aws configure list --profile zataCompare the access key with the list on Access Keys in the Zata console.
-
Enter the secret key again. Copy it from the key file you downloaded when you created the key — the console does not show a secret key again. If you no longer have the file, rotate the key or create a new one (see Access keys).
AWS CLIaws configure set aws_secret_access_key YOUR_SECRET_KEY --profile zatarclonerclone config update zata secret_access_key=YOUR_SECRET_KEY -
Test the keys with the AWS CLI (set it up if you have not):
aws s3 ls s3://my-bucket --profile zataIf the AWS CLI works with the same keys, the keys are right and the other tool's settings are the problem.
If a forgotten AWS_SECRET_ACCESS_KEY environment variable is set, it overrides the profile. See Clock and credentials to find out which keys a tool picks up.
rclone and Go apps
Something between your tool and Zata changes the Accept-Encoding header. Tools that include this header in the signature fail on every request with SignatureDoesNotMatch. Python tools (boto3, s3cmd) and the AWS CLI are not affected.
rclone v1.70 and newer — turn off signing of that header. Also set no_check_bucket, which sub-user keys need:
rclone config update zata sign_accept_encoding=false no_check_bucket=true
The remote in rclone.conf then contains:
sign_accept_encoding = false
no_check_bucket = true
rclone added sign_accept_encoding in v1.70 (rclone changelog, 2025-06-17). On rclone before v1.70 the setting does nothing — it is silently ignored — so if you hit this error on an older rclone, update rclone to v1.70 or newer. Very old versions such as v1.53 from Ubuntu's apt do not sign the header and are not affected. Apps built on rclone, such as S3 Drive, need the same two settings. Full setup: rclone on Linux, rclone on Windows, rclone GUI.
AWS SDK for Go v2 — remove the header before the request is signed. Add this middleware to the client options:
// Leave Accept-Encoding out of the signature.
func unsignedAcceptEncoding(stack *middleware.Stack) error {
return stack.Finalize.Insert(middleware.FinalizeMiddlewareFunc("zataUnsignedAcceptEncoding",
func(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (middleware.FinalizeOutput, middleware.Metadata, error) {
if r, ok := in.Request.(*smithyhttp.Request); ok {
r.Header.Del("Accept-Encoding")
}
return next.HandleFinalize(ctx, in)
}), "Signing", middleware.Before)
}
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.BaseEndpoint = aws.String("https://idr01.zata.ai")
o.UsePathStyle = true
o.APIOptions = append(o.APIOptions, unsignedAcceptEncoding)
})
The complete client, with imports and the checksum settings, is on the Go page.
Velero currently fails with SignatureDoesNotMatch on Zata for this reason, and no setting in Velero fixes it.
A proxy changes the request
The signature covers the host name, the path, the query string, the signed headers and the body. A proxy, TLS-inspection appliance or reverse proxy that changes any of them — for example by decoding %20 or merging // in the path — breaks the signature.
Run the same command once with the proxy bypassed for Zata. Enter host names, not URLs:
- Linux / macOS
- Windows (PowerShell)
export NO_PROXY=idr01.zata.ai,bom01.zata.ai
aws s3 ls s3://my-bucket --profile zata
$env:NO_PROXY="idr01.zata.ai,bom01.zata.ai"
aws s3 ls s3://my-bucket --profile zata
If it works now, ask your network team to pass Zata traffic through unchanged. More network checks are on Network and certificates.
Special characters in file names
Zata accepts object names with spaces, +, &, ; and non-English (Unicode) characters. If only such names fail, upload the same name with the AWS CLI:
aws s3 cp "test file+1.txt" "s3://my-bucket/test file+1.txt" --profile zata
If this works, the problem is in how your tool encodes the name. Update the tool, or report it to its vendor.
s3cmd
In ~/.s3cfg, host_bucket must be the plain host name. A value with a bucket placeholder such as idr01.zata.ai/%(bucket)s fails with SignatureDoesNotMatch:
host_base = idr01.zata.ai
host_bucket = idr01.zata.ai
For Mumbai, use bom01.zata.ai in both lines. See s3cmd.
Presigned upload links
A presigned upload (PUT) link is signed for one exact request:
-
If the link was created with a
ContentType, the upload must send exactly thatContent-Typeheader, or Zata answers 403:curl -X PUT -H "Content-Type: text/plain" --upload-file upload.txt "UPLOAD_URL" -
If the link was created without a
ContentType, send noContent-Typeheader. Some HTTP libraries add one on their own, which also gives 403. -
A link stops working when it expires, or when the key that signed it is deleted or deactivated.
To share a file without code, use the console: see Share a file.
See the real error
Zata's error responses contain an error code but no message text, so look for the code. The debug output contains your access key ID — remove it before you share the output with anyone.
| Tool | Run | Look for |
|---|---|---|
| AWS CLI | add --debug to the command | <Code> in the Response body line; CanonicalRequest and StringToSign show what was signed |
| rclone | add -vv --dump headers | the HTTP status and api error with the code in the last line |
| s3fs | mount with -f -o dbglevel=info | the failing request and its HTTP response code |
| boto3 | catch ClientError | e.response["Error"]["Code"] |
To print only the error code from the AWS CLI:
aws s3 ls s3://my-bucket --profile zata --debug 2>&1 | grep -o "<Code>[^<]*</Code>"
Still stuck?
Contact Zata support (see Get support) and include:
- the tool and its version (
aws --version,rclone version,s3fs --version) - the endpoint you use and the region of the bucket (Indore or Mumbai)
- the exact error code, and the
RequestIdfrom the error response - the debug output from above, with access keys removed
Zata support can check the server logs for your request.