Skip to main content

Error Handling

Every error thrown by the SDK is an instance of RGWError with structured properties.

Error Hierarchy

Error
└── RGWError (base — all SDK errors extend this)
├── RGWValidationError (400 / client-side validation)
├── RGWNotFoundError (404)
├── RGWAuthError (403)
├── RGWConflictError (409)
├── RGWRateLimitError (429, retryable)
└── RGWServiceError (5xx, retryable)

HTTP Status Mapping

HTTP StatusError ClassRetryableWhen
(pre-request)RGWValidationErrorNoInvalid input (missing uid, bad params)
400RGWValidationErrorNoBad request parameters
403RGWAuthErrorNoInvalid credentials or missing capabilities
404RGWNotFoundErrorNoUser, bucket, key, or subuser not found
409RGWConflictErrorNoResource already exists
429RGWRateLimitErrorYesRate limit exceeded
5xxRGWServiceErrorYesRGW server error
NetworkRGWError (code: NetworkError)YesConnection refused, DNS failure, etc.
TimeoutRGWError (code: Timeout)YesRequest exceeded timeout

Error Properties

Every error exposes these properties:

catch (err) {
if (err instanceof RGWError) {
err.message; // Human-readable description
err.statusCode; // HTTP status (undefined for validation errors)
err.code; // RGW error code from the response body
err.name; // Error class name (e.g. "RGWNotFoundError")
}
}

The code Field — RGW Error Codes

RGW returns specific error codes in its response body. The SDK preserves these on the code property so you can distinguish between different error scenarios:

400 Codes (RGWValidationError)

CodeMeaning
InvalidArgumentA query parameter has an invalid value
InvalidBucketNameBucket name does not follow naming rules
MalformedPolicyInvalid policy document
ValidationErrorClient-side validation (no HTTP call made)

404 Codes (RGWNotFoundError)

CodeMeaning
NoSuchUserUser UID does not exist
NoSuchBucketBucket name does not exist
NoSuchKeyAccess key does not exist
NoSuchSubUserSubuser does not exist

403 Codes (RGWAuthError)

CodeMeaning
AccessDeniedAdmin user lacks required capabilities
InvalidAccessKeyIdAccess key is invalid or does not exist
SignatureDoesNotMatchSecret key is incorrect

409 Codes (RGWConflictError)

CodeMeaning
UserAlreadyExistsUID is already in use
BucketAlreadyExistsBucket name is taken
KeyExistsAccess key already assigned
EmailExistsEmail address already in use

429 Codes (RGWRateLimitError)

CodeMeaning
TooManyRequestsRate limit exceeded
SlowDownRate limit exceeded (S3-style code)

5xx Codes (RGWServiceError)

CodeMeaning
InternalErrorRGW internal failure
ServiceUnavailableRGW temporarily unavailable

Usage Examples

Catch specific error types

import {
RGWNotFoundError,
RGWAuthError,
RGWConflictError,
RGWRateLimitError,
RGWServiceError,
} from 'radosgw-admin';

try {
await rgw.users.get('alice');
} catch (err) {
if (err instanceof RGWNotFoundError) {
console.log(`User not found (${err.code})`); // "User not found (NoSuchUser)"
} else if (err instanceof RGWAuthError) {
console.log('Check admin credentials');
} else if (err instanceof RGWConflictError) {
console.log('Resource already exists');
} else if (err instanceof RGWRateLimitError) {
console.log('Rate limited — try again later');
} else if (err instanceof RGWServiceError) {
console.log(`Server error: ${err.statusCode}`);
}
}

Inspect the RGW error code

try {
await rgw.users.create({ uid: 'alice', displayName: 'Alice' });
} catch (err) {
if (err instanceof RGWConflictError && err.code === 'EmailExists') {
console.log('Email is already used by another user');
} else if (err instanceof RGWConflictError && err.code === 'UserAlreadyExists') {
console.log('UID is already taken');
}
}

Handle network errors

try {
await rgw.users.list();
} catch (err) {
if (err instanceof RGWError) {
if (err.code === 'NetworkError') {
console.log('Cannot reach RGW — check host and port');
} else if (err.code === 'Timeout') {
console.log(`Request timed out — increase timeout config`);
}
}
}

Retry Behavior

When maxRetries > 0, these errors are automatically retried with exponential backoff + jitter:

  • 429 (RGWRateLimitError) — rate limit exceeded
  • 5xx (RGWServiceError) — server errors
  • Network errors — connection refused, DNS failure, etc.
  • Timeouts — request exceeded timeout

Non-retryable errors (400, 403, 404, 409) fail immediately on the first attempt.

const rgw = new RadosGWAdminClient({
host: '...',
accessKey: '...',
secretKey: '...',
maxRetries: 3, // retry up to 3 times
retryDelay: 200, // 200ms base delay with jitter
});

Destructive Operation Warnings

Methods that permanently delete data emit a console.warn before executing:

  • users.delete({ purgeData: true })
  • buckets.delete({ purgeObjects: true })
  • usage.trim({ removeAll: true })

To suppress in CI/automation, redirect stderr or patch console.warn.