{"record":{"id":"a94741dc619eafea","repo":"HumanSignal/label-studio","slug":"it-seems-access-keys-are-incorrect","errorCode":null,"errorMessage":"It seems access keys are incorrect","messagePattern":"It seems access keys are incorrect","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/io_storages/s3/serializers.py","lineNumber":72,"sourceCode":"            raise ValidationError('Wrong credentials for S3 {bucket_name}'.format(bucket_name=storage.bucket))\n        except ClientError as e:\n            if (\n                e.response.get('Error').get('Code') in ['SignatureDoesNotMatch', '403']\n                or e.response.get('ResponseMetadata').get('HTTPStatusCode') == 403\n            ):\n                raise ValidationError(\n                    'Cannot connect to S3 {bucket_name} with specified AWS credentials'.format(\n                        bucket_name=storage.bucket\n                    )\n                )\n            if (\n                e.response.get('Error').get('Code') in ['NoSuchBucket', '404']\n                or e.response.get('ResponseMetadata').get('HTTPStatusCode') == 404\n            ):\n                raise ValidationError('Cannot find bucket {bucket_name} in S3'.format(bucket_name=storage.bucket))\n        except TypeError as e:\n            logger.info(f'It seems access keys are incorrect: {e}', exc_info=True)\n            raise ValidationError('It seems access keys are incorrect')\n        except KeyError:\n            raise ValidationError(f'{storage.url_scheme}://{storage.bucket}/{storage.prefix} not found.')\n        return data\n\n\nclass S3ImportStorageSerializer(S3StorageSerializerMixin, ImportStorageSerializer):\n    type = StorageTypeField(default=os.path.basename(os.path.dirname(__file__)))\n    presign = serializers.BooleanField(required=False, default=True)\n\n    def validate_s3_endpoint(self, value):\n        if value and settings.SSRF_PROTECTION_ENABLED:\n            validate_url_for_ssrf(value, block_local_urls=True)\n        return value\n\n    class Meta:\n        model = S3ImportStorage\n        fields = '__all__'\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/io_storages/s3/serializers.py#L54-L90","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set real aws_access_key_id / aws_secret_access_key values on the storage payload.","Or remove explicit credential fields and rely on a working IAM instance profile / env credentials on the host.","Check the server log line 'It seems access keys are incorrect: {e}' for the exact TypeError to identify which parameter is None."],"exampleFix":"// before\n{\"bucket\": \"my-bucket\", \"aws_access_key_id\": null, \"aws_secret_access_key\": null}\n\n// after\n{\"bucket\": \"my-bucket\", \"aws_access_key_id\": \"AKIA...\", \"aws_secret_access_key\": \"secret\"}","handlingStrategy":"validation","validationCode":"def ensure_str(value, name: str) -> str:\n    if not isinstance(value, str) or not value:\n        raise ValueError(f'{name} must be a non-empty string, got {value!r}')\n    return value\n\naccess_key = ensure_str(payload.get('aws_access_key_id'), 'aws_access_key_id')\nsecret_key = ensure_str(payload.get('aws_secret_access_key'), 'aws_secret_access_key')","typeGuard":"def credentials_are_strings(data: dict) -> bool:\n    return all(\n        isinstance(data.get(k), str) and bool(data.get(k))\n        for k in ('aws_access_key_id', 'aws_secret_access_key')\n        if k in data\n    )","tryCatchPattern":"try:\n    serializer.is_valid(raise_exception=True)\nexcept ValidationError as e:\n    if 'access keys are incorrect' in str(e.detail):\n        # a TypeError occurred: some credential field was None — inspect the server log","preventionTips":["Never pass null/None AWS key fields; omit them entirely to fall back to env/instance-role creds.","Check the INFO log 'It seems access keys are incorrect: {e}' to see which parameter was None.","Validate your YAML/JSON config doesn't coerce keys to null (e.g. empty values).","Run a boto3 client construction smoke test in CI with the same env."],"tags":["s3","aws","credentials","typeerror","serializer"],"backgroundTag":"invalid-aws-credentials","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}