awslabs / aws-sdk-kotlin

Multiplatform AWS SDK for Kotlin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

getObjectAttributes fails with "We encountered an internal error. Please try again." if key contains chinese characters

acarlsen opened this issue · comments

Describe the bug

In my scenario I upload a file using S3 Client putObject method, key string contains chinese characters.
For example a file named 0103雲端備份訂價表.xlsx.

The upload works fine.

I then want to get attributes of the uploaded file to verify different things using getObjectAttributes - I use the same key as for upload. This fails with the following error.

aws.sdk.kotlin.services.s3.model.S3Exception: We encountered an internal error. Please try again.
at aws.sdk.kotlin.services.s3.serde.GetObjectAttributesOperationDeserializerKt.throwGetObjectAttributesError(GetObjectAttributesOperationDeserializer.kt:81)
at aws.sdk.kotlin.services.s3.serde.GetObjectAttributesOperationDeserializerKt.access$throwGetObjectAttributesError(GetObjectAttributesOperationDeserializer.kt:1)
at aws.sdk.kotlin.services.s3.serde.GetObjectAttributesOperationDeserializerKt$throwGetObjectAttributesError$1.invokeSuspend(Unknown Source:13)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:280)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source:1)

Expected behavior

I expect getObjectAttributes function call to not fail.

Current behavior

Calling getObjectAttributes works for other keys, but fails consistently for keys with chinese characters (and also possibly other special characters). It works with Java SDK (getObjectMetadata).

Steps to Reproduce

Upload a file to a bucket:

val request = PutObjectRequest {
    bucket = "somebucket"
    key = "0103雲端備份訂價表.xlsx"
    body = file.asByteStream()
}
s3Client.putObject(request)

Try to get object attributes:

val request = GetObjectAttributesRequest {
    bucket = "somebucket"
    key = "0103雲端備份訂價表.xlsx"
    objectAttributes = listOf(
       ObjectAttributes.ObjectSize,
       ObjectAttributes.Checksum,
    )
}
s3Client.getObjectAttributes(request)

Possible Solution

None

Context

I want to get metadata for an object with chinese characters in key.

AWS Kotlin SDK version used

1.0.8

Platform (JVM/JS/Native)

JVM

Operating System and version

Android 14

Thanks for the bug report, I'm able to recreate this. Interestingly I'm seeing the same thing with the CLI and AWS SDK for Java v2:

CLI

>  aws --version
aws-cli/2.14.5 Python/3.11.6 Darwin/22.6.0 source/x86_64 prompt/off


> aws s3api get-object-attributes --bucket <my-bucket> --key 0103雲端備份訂價表.xlsx --object-attributes ObjectSize
An error occurred (InternalError) when calling the GetObjectAttributes operation (reached max retries: 2): We encountered an internal error. Please try **again.**

AWS SDSK for Java v2

    val javaV2Resp = S3Client.create().getObjectAttributes { builder ->
        builder.bucket(bucketName)
            .key(objKey)
            .objectAttributes(software.amazon.awssdk.services.s3.model.ObjectAttributes.OBJECT_SIZE)
            .build()
    }
    println(javaV2Resp)

Exception in thread "main" software.amazon.awssdk.services.s3.model.S3Exception: We encountered an internal error. Please try again. (Service: S3, Status Code: 500, ...)

Other things I noticed:

  • One request on v0.32.0-beta made it through fine and then failed on subsequent requests
  • AWS CLI, AWS SDK for Java v2, and AWS SDK for Kotlin use the same encoding for the object key (0103%E9%9B%B2%E7%AB%AF%E5%82%99%E4%BB%BD%E8%A8%82%E5%83%B9%E8%A1%A8.xlsx) in the URI
  • AWS CLI, AWS SDK for Java v2, and AWS SDK for Kotlin are all able to read back the content via GetObject

Given this is happening in multiple SDKs and the CLI I'll be opening a ticket with S3

internal: V1140391686

Just FYI I should have been more clear, I meant it worked in Java SDK for Android - the SDK for Android doesn't seem to have the getObjectAttributes method at all.

This appears to be confirmed a service side issue but I have no ETA for a fix at the moment.

Any workarounds? With the Android Java SDK there is the option to retrieve metadata using s3client.getObjectMetadata().

Is there a similar command in the Kotlin SDK? I can't seem to find it..

Yeah under the hood that method is just calling the HeadObject operation. I'm not sure why it's renamed in the Android SDK.

val metadata = s3.headObject { 
    bucket = myBucket
    key = myKey
}

println(metadata)

See the Kotlin API ref docs for headObject

Thanks, that works fine. :-)