> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.zata.prathamchopde.site/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.zata.prathamchopde.site/_mcp/server.

# Signature errors

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.

> **Note**
>
> 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](#the-secret-key-is-wrong)                    |
| `SignatureDoesNotMatch` on every rclone command (rclone v1.66 or newer) | rclone signs the `Accept-Encoding` header, which changes on the way to Zata                | [Set `sign_accept_encoding = false`](#rclone-and-go-apps)                 |
| `SignatureDoesNotMatch` from a Go app (AWS SDK for Go v2)               | Same as rclone                                                                             | [Leave `Accept-Encoding` out of the signature](#rclone-and-go-apps)       |
| Works on one network, fails on another (for example the office)         | A proxy or security appliance changes the request                                          | [Bypass the proxy for Zata](#a-proxy-changes-the-request)                 |
| Only files with spaces, `+` or non-English characters fail              | The tool encodes the name differently                                                      | [Test the name with the AWS CLI](#special-characters-in-file-names)       |
| s3cmd: `403 (SignatureDoesNotMatch)`                                    | `host_bucket` contains a bucket placeholder                                                | [Fix `host_bucket`](#s3cmd)                                               |
| `403` when you upload with a presigned link                             | The `Content-Type` header differs from the one in the link                                 | [Send the same `Content-Type`](#presigned-upload-links)                   |
| `InvalidAccessKeyId`                                                    | The access key ID is wrong or from the other region — not a signature problem              | See [Wrong endpoint or region](/help/troubleshooting/endpoint-and-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`](#see-the-real-error)                     |

## 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):

   ```bash
   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](/access/access-keys)).

   **`AWS CLI`**

   ```bash AWS CLI
   aws configure set aws_secret_access_key YOUR_SECRET_KEY --profile zata
   ```

   **`rclone`**

   ```bash rclone
   rclone config update zata secret_access_key=YOUR_SECRET_KEY
   ```

3. Test the keys with the AWS CLI ([set it up](/connect/command-line/aws-cli) if you have not):

   ```bash
   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.

> **Tip**
>
> If a forgotten `AWS_SECRET_ACCESS_KEY` environment variable is set, it overrides the profile. See [Clock and credentials](/help/troubleshooting/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:

```bash
rclone config update zata sign_accept_encoding=false no_check_bucket=true
```

The remote in `rclone.conf` then contains:

```ini
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](/connect/desktop-apps/s3-drive), need the same two settings. Full setup: [rclone on Linux](/connect/command-line/rclone-linux), [rclone on Windows](/connect/command-line/rclone-windows), [rclone GUI](/connect/command-line/rclone-gui).

**AWS SDK for Go v2** — remove the header before the request is signed. Add this middleware to the client options:

```go
// 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](/connect/code/go) page.

> **Note**
>
> 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

```bash
export NO_PROXY=idr01.zata.ai,bom01.zata.ai
aws s3 ls s3://my-bucket --profile zata
```

#### Windows (PowerShell)

```powershell
$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](/help/troubleshooting/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:

```bash
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`:

```ini
host_base = idr01.zata.ai
host_bucket = idr01.zata.ai
```

For Mumbai, use `bom01.zata.ai` in both lines. See [s3cmd](/connect/command-line/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 that `Content-Type` header, or Zata answers 403:

  ```bash
  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](/buckets/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:

```bash
aws s3 ls s3://my-bucket --profile zata --debug 2>&1 | grep -o "<Code>[^<]*</Code>"
```

## Still stuck?

Contact Zata support (see [Get support](/help/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.