HumanSignal/label-studio · error · ValidationError
Wrong credentials for S3 {bucket_name}
Error message
Wrong credentials for S3 {bucket_name} What it means
In S3StorageSerializerMixin.validate(), after building the storage object, validate_connection() is called; if it raises a botocore ParamValidationError the serializer raises ValidationError('Wrong credentials for S3 {bucket_name}'). Note the message is a plain .format() on a literal not containing braces placement for the value, so the rendered text keeps the literal '{bucket_name}'. It signals malformed/insufficient AWS parameters rather than an auth rejection from AWS.
Source
Thrown at label_studio/io_storages/s3/serializers.py:54
def validate(self, data):
data = super().validate(data)
if not data.get('bucket', None):
return data
storage = self.instance
if storage:
for key, value in data.items():
setattr(storage, key, value)
else:
if 'id' in self.initial_data:
storage_object = self.Meta.model.objects.get(id=self.initial_data['id'])
for attr in self.secure_fields:
data[attr] = data.get(attr) or getattr(storage_object, attr)
storage = self.Meta.model(**data)
try:
storage.validate_connection()
except ParamValidationError:
raise ValidationError('Wrong credentials for S3 {bucket_name}'.format(bucket_name=storage.bucket))
except ClientError as e:
if (
e.response.get('Error').get('Code') in ['SignatureDoesNotMatch', '403']
or e.response.get('ResponseMetadata').get('HTTPStatusCode') == 403
):
raise ValidationError(
'Cannot connect to S3 {bucket_name} with specified AWS credentials'.format(
bucket_name=storage.bucket
)
)
if (
e.response.get('Error').get('Code') in ['NoSuchBucket', '404']
or e.response.get('ResponseMetadata').get('HTTPStatusCode') == 404
):
raise ValidationError('Cannot find bucket {bucket_name} in S3'.format(bucket_name=storage.bucket))
except TypeError as e:
logger.info(f'It seems access keys are incorrect: {e}', exc_info=True)
raise ValidationError('It seems access keys are incorrect')View on GitHub (pinned to 0b49e9b539)
Solutions
- Provide valid AWS credentials (aws_access_key_id / aws_secret_access_key / security_token) or rely on a correctly configured instance role.
- If using secure_mode updates, ensure stored secure fields actually exist on the existing storage_object.
- Set the correct region_name so the boto3 client can be constructed.
- Check the server log for the underlying ParamValidationError report for the exact bad parameter.
Example fix
// before
{"bucket": "my-bucket", "aws_access_key_id": "", "aws_secret_access_key": null}
// after
{"bucket": "my-bucket", "aws_access_key_id": "AKIA...", "aws_secret_access_key": "secret", "region_name": "us-east-1"} Defensive patterns
Strategy: validation
Validate before calling
import os
def aws_credentials_present() -> bool:
return all([
os.environ.get('AWS_ACCESS_KEY_ID'),
os.environ.get('AWS_SECRET_ACCESS_KEY'),
os.environ.get('AWS_REGION') or os.environ.get('AWS_DEFAULT_REGION'),
])
if not aws_credentials_present():
raise ValueError('Set AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_REGION first') Type guard
def has_credential_fields(data: dict) -> bool:
keys = ('aws_access_key_id', 'aws_secret_access_key', 'region_name')
return any(isinstance(data.get(k), str) and data[k] for k in keys) Try / catch
try:
serializer.is_valid(raise_exception=True)
except ValidationError as e:
if 'Wrong credentials for S3' in str(e.detail):
# underlying ParamValidationError: check which AWS param was None/invalid
logger.warning('S3 param validation failed for %s; check keys/region', bucket) Prevention
- Never submit empty-string or null AWS credential fields; omit them to use instance roles.
- In secure_mode, confirm the existing storage actually stores the secure fields you rely on.
- Always set region_name with custom credentials.
- Rotate keys in sync — update Label Studio storage when AWS keys change.
When it happens
Trigger: storage.validate_connection() raising ParamValidationError during serializer validation — e.g. missing or wrong-typed aws_access_key_id/aws_secret_access_key/region/bucket parameters, often because secure_mode merges undefined attrs into None.
Common situations: Empty AWS keys in env (None passed to boto3 client); secure_mode storage update omitting credential fields so they resolve to None; region unset so client construction fails validation; expired/rotated keys removed from settings.
Related errors
- exc.kwargs['report']
- It seems access keys are incorrect
- {connection validation error}
- Cannot find bucket {bucket_name} in S3
- {storage.url_scheme}://{storage.bucket}/{storage.prefix} not
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/82f08f7f320128ab.
Report an issue: GitHub.