HumanSignal/label-studio · error · ValidationError

It seems access keys are incorrect

Error message

It seems access keys are incorrect

What it means

In S3StorageSerializerMixin.validate(), if storage.validate_connection() raises a TypeError (typically boto3 failing because credentials are None/malformed, e.g. expecting str got NoneType), the serializer logs the traceback and raises ValidationError('It seems access keys are incorrect'). It is a client-side type failure caused by missing/None credential fields rather than an AWS response.

Source

Thrown at label_studio/io_storages/s3/serializers.py:72

            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')
        except KeyError:
            raise ValidationError(f'{storage.url_scheme}://{storage.bucket}/{storage.prefix} not found.')
        return data


class S3ImportStorageSerializer(S3StorageSerializerMixin, ImportStorageSerializer):
    type = StorageTypeField(default=os.path.basename(os.path.dirname(__file__)))
    presign = serializers.BooleanField(required=False, default=True)

    def validate_s3_endpoint(self, value):
        if value and settings.SSRF_PROTECTION_ENABLED:
            validate_url_for_ssrf(value, block_local_urls=True)
        return value

    class Meta:
        model = S3ImportStorage
        fields = '__all__'

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Set real aws_access_key_id / aws_secret_access_key values on the storage payload.
  2. Or remove explicit credential fields and rely on a working IAM instance profile / env credentials on the host.
  3. Check the server log line 'It seems access keys are incorrect: {e}' for the exact TypeError to identify which parameter is None.

Example fix

// before
{"bucket": "my-bucket", "aws_access_key_id": null, "aws_secret_access_key": null}

// after
{"bucket": "my-bucket", "aws_access_key_id": "AKIA...", "aws_secret_access_key": "secret"}
Defensive patterns

Strategy: validation

Validate before calling

def ensure_str(value, name: str) -> str:
    if not isinstance(value, str) or not value:
        raise ValueError(f'{name} must be a non-empty string, got {value!r}')
    return value

access_key = ensure_str(payload.get('aws_access_key_id'), 'aws_access_key_id')
secret_key = ensure_str(payload.get('aws_secret_access_key'), 'aws_secret_access_key')

Type guard

def credentials_are_strings(data: dict) -> bool:
    return all(
        isinstance(data.get(k), str) and bool(data.get(k))
        for k in ('aws_access_key_id', 'aws_secret_access_key')
        if k in data
    )

Try / catch

try:
    serializer.is_valid(raise_exception=True)
except ValidationError as e:
    if 'access keys are incorrect' in str(e.detail):
        # a TypeError occurred: some credential field was None — inspect the server log

Prevention

When it happens

Trigger: validate_connection() constructing the boto3 client with aws_access_key_id/aws_secret_access_key equal to None (empty or absent fields), so botocore raises TypeError while signing.

Common situations: Storage created without credentials while the machine has no instance role/env credentials; secure_mode pulling nonexistent attrs as None; env vars like AWS_ACCESS_KEY_ID unset; YAML/JSON config quoting mistakes turning keys into null.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/a94741dc619eafea. Report an issue: GitHub.