🇬🇧 English | 🇺🇦 Українська
7. Errors and Diagnostics¶
Three layers of a response¶
Every result carries three things, and it's worth reading them in exactly this order.
| What | What it's for | Example |
|---|---|---|
| Result Code | Branching in code | PermissionDenied |
| Error Code | Logs and exact checks | AccessDenied |
| Diagnostic Hint | What to change | "The keys are valid, but the policy doesn't allow this action…" |
Providers answer with codes like SignatureDoesNotMatch — precise, but saying nothing about the
cause. And the cause is almost always a configuration mistake unrelated to the wording. The hint
translates one into the other.
On Failure
└─► Print String (Get S3 Diagnostic Hint)
Or, in one line for a log: Get S3 Result Summary.
Result Code¶
| Value | What happened | Where to look |
|---|---|---|
Success |
Everything worked | — |
Partial Success |
A batch operation went through, some items didn't | Error Count, the Results array |
Network Error |
The request never arrived: DNS, routing, connection refused, TLS | Endpoint, scheme, network |
Timeout |
The response didn't arrive in time | Timeout Seconds, the connection |
Authentication Error |
The keys were rejected | Secret, region, system clock |
Permission Denied |
The keys are valid, but the action isn't allowed | IAM policy or bucket policy |
Not Found |
No such bucket or object | Name, case |
Already Exists |
The bucket name is taken | A different name |
Precondition Failed |
The object changed during the transfer | Read it again — 5. Transfers |
Invalid Request |
The request was rejected as malformed | Almost always a bug in your code |
Throttled |
The provider is rate-limiting | Max Retries, the number of concurrent operations |
Server Error |
A failure on the provider's side | The provider's status page |
Cancelled |
Cancelled by a call | — |
Note the difference between Authentication Error and Permission Denied. Both arrive as HTTP
403, but the fix is different for each: the first is a key problem, the second a policy
problem. The plugin tells them apart by the provider's error code.
Precondition Failed (HTTP 412) isn't a connection failure or a misconfiguration: the object in
storage was rewritten while it was being read. The plugin refuses to stitch two versions
together into one file and reports this instead of handing back a corrupted result.
Common errors and what to do about them¶
SignatureDoesNotMatch¶
The most common first-day error.
If the provider isn't Amazon and Path Style Addressing is off — that's almost certainly it. Pick your provider from the settings list, and the addressing style gets set correctly.
If addressing is already correct, check in this order:
- The secret key — a stray space at the start or end from copy-pasting.
- The region — it's part of the signature and has to match the bucket's region.
- The system clock — a signature is valid within a ±15-minute window.
The key identifier itself is definitely correct with this particular error: the provider recognized it, otherwise it would have answered differently.
RequestTimeTooSkewed¶
The machine's clock is more than 15 minutes off from the server. Turn on time sync.
InvalidAccessKeyId¶
The provider doesn't know this key. If you're using temporary keys — make sure you're passing the session token too: without it the key looks nonexistent, even when the key and secret are correct.
AccessDenied¶
The keys are valid, but the policy doesn't allow this specific action. This isn't a key problem — fix the IAM policy or the bucket policy.
NoSuchBucket¶
No such bucket exists in this region, for this account.
On MinIO this often means something else: MinIO doesn't create buckets on first request. Create it with the S3 Create Bucket node or through the MinIO console.
PermanentRedirect / HTTP 301¶
The bucket lives in a different region. Fix the Region field, and the endpoint adjusts itself on Amazon S3.
NoSuchKey¶
No such object exists. Keys are case-sensitive and don't start with a slash:
saves/player.sav, not /saves/player.sav.
EntityTooSmall¶
A multipart upload part is smaller than 5 MB — the minimum S3 requires for every part except the
last. Raise Multipart Part Size Bytes to 5242880 or more. This shouldn't normally happen: the
plugin already raises the value to the minimum on its own.
403 on List Buckets¶
Listing buckets requires account-level permission, which keys scoped to "one bucket" don't have. Cloudflare R2 doesn't implement this operation at all and always answers with a failure — every other operation works there fine.
If you already know the bucket you need, this operation isn't necessary.
Logs¶
The plugin writes to the LogDemoS3 category.
Log LogDemoS3 Verbose // one line per request: method, address
Log LogDemoS3 VeryVerbose // plus every signed header
Or in DefaultEngine.ini:
[Core.Log]
LogDemoS3=Verbose
VeryVerbose prints the Authorization header along with the credential scope — turn it on
when you're specifically debugging the signature, and off afterward.
The secret key never makes it into the logs. The credential description you'll see looks like
AKIA... (temporary) — enough to tell one profile from another, nothing more.
Test buttons¶
The fastest way to check whether a configuration works — Project Settings → Plugins → S3 Compatible Storage:
| Button | What it checks |
|---|---|
| Test Connection | Endpoint, addressing style, signature, bucket access |
| List Objects | That the bucket is readable, and what's in it |
| Run Round Trip Check | The full cycle: write, read, verify bytes, delete |
They use the exact same code as the packaged game, so a green result means a working configuration, not just a syntactically valid one. The report appears right there, along with hints for any errors.
When nothing helps¶
- Turn on
Log LogDemoS3 VeryVerboseand make one request. - Compare the address in the log against what you expect: is the host right, is the bucket where it should be, are special characters in the key encoded.
- Take the
Request Idfrom the result — providers can look it up in their own logs, and it's the single most useful thing to hand support.
Next: 8. Providers