Skip to navigation

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 seeMost likely causeFix
SignatureDoesNotMatch in every toolThe secret key is wrong: a missing character, or an extra space or line break from pastingEnter the secret key again
SignatureDoesNotMatch on every rclone command (rclone v1.66 or newer)rclone signs the Accept-Encoding header, which changes on the way to ZataSet sign_accept_encoding = false
SignatureDoesNotMatch from a Go app (AWS SDK for Go v2)Same as rcloneLeave Accept-Encoding out of the signature
Works on one network, fails on another (for example the office)A proxy or security appliance changes the requestBypass the proxy for Zata
Only files with spaces, + or non-English characters failThe tool encodes the name differentlyTest the name with the AWS CLI
s3cmd: 403 (SignatureDoesNotMatch)host_bucket contains a bucket placeholderFix host_bucket
403 when you upload with a presigned linkThe Content-Type header differs from the one in the linkSend the same Content-Type
InvalidAccessKeyIdThe access key ID is wrong or from the other region — not a signature problemSee Wrong endpoint or region
AWS CLI: argument of type 'NoneType' is not a container or iterableThe AWS CLI cannot display Zata’s errorRun 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.

  1. 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 zata

    Compare the access key with the list on Access Keys in the Zata console.

  2. 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 CLI
    aws configure set aws_secret_access_key YOUR_SECRET_KEY --profile zata
    rclone
    rclone config update zata secret_access_key=YOUR_SECRET_KEY
  3. Test the keys with the AWS CLI (set it up if you have not):

    aws s3 ls s3://my-bucket --profile zata

    If 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.66 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

Older rclone versions (such as v1.53 from Ubuntu’s apt) do not have this setting 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:

export 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.

A presigned upload (PUT) link is signed for one exact request:

  • If the link was created with a ContentType, the upload must send exactly that Content-Type header, 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 no Content-Type header. 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.

ToolRunLook for
AWS CLIadd --debug to the command<Code> in the Response body line; CanonicalRequest and StringToSign show what was signed
rcloneadd -vv --dump headersthe HTTP status and api error with the code in the last line
s3fsmount with -f -o dbglevel=infothe failing request and its HTTP response code
boto3catch ClientErrore.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 RequestId from the error response
  • the debug output from above, with access keys removed

Zata support can check the server logs for your request.