Can't use Spaces via Amazon S3 SDK

February 10, 2018 2.1k views
API Java Ubuntu

I’m trying to perform a PUT operation towards Spaces using AWS S3 Java SDK, but I keep getting the same error.

Here’s the definition of the client:

    public AmazonS3 spaces() {
        BasicAWSCredentials credentials = new BasicAWSCredentials(…);
        return AmazonS3ClientBuilder.standard().
                withCredentials(new AWSStaticCredentialsProvider(credentials)).
                withPathStyleAccessEnabled(true).
                withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("bucketname.ams3.digitaloceanspaces.com", "ams3")).
                build();
    }

Here’s usage:

spaces.putObject("bucketname", fullPath, tempFile);

And the error is:

com.amazonaws.services.s3.model.AmazonS3Exception: Bad request (Service: Amazon S3; Status Code: 400; Error Code: 400 Bad request; Request ID: null; S3 Extended Request ID: null)

SDK version:

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.274</version>
        </dependency>

I tried to replace AwsClientBuilder.EndpointConfiguration("bucketname.ams3.digitaloceanspaces.com", "ams3") with AwsClientBuilder.EndpointConfiguration("ams3.digitaloceanspaces.com", "ams3"), but it also didn’t work.

And when I try to GET the file, I surprisingly get a different error:

com.amazonaws.services.s3.model.AmazonS3Exception: null (Service: Amazon S3; Status Code: 403; Error Code: SignatureDoesNotMatch; Request ID: …; S3 Extended Request ID: …)

Although I’m pretty sure that I’ve specified key and secret correctly: I double-checked it.

1 comment
  • I found that if I listObject for the bucket before putObject, it works. I have been trying to get pre-signed url to upload all day. I am giving up on this. This product is incomplete and/or super buggy. Its not s3 compatible as they claim.

4 Answers

I am facing the same issue with AWS SDK: 1.11.528

(surprisingly after almost one and half years this is still not resolved)

Maybe a better strategy is not to claim DO spaces are S3 compatible.

  • Eventually, I’ve given up using DO and switched completely to AWS.

    • For what’s worth, the root cause is because my destination file full contains a ’$’, which needs to be explicitly url escaped. However the error message is extremely unclear.

      Another issue I had with DO spaces are the bulk delete performance are disappointing.

      In general it’s not a product as great as other DO services.

      • I am experiencing the same issue when accessing files using whitespace (and therefore also becoming url encoded (by the AWS SDK). This issue seems to only appear for private objects since the URL given to the file through the DO Dashboard are identical to what AWS SDK attempts to access.

I am facing the same problem, Did anyone resolve this or Digital Ocean is not sure about the solution?

I know that the question is old but I faced the same issue and RESOLVED it. In my case, the problem was on the wrong date. The date was set up a few days in the future and I had the issue. After I put the correct date/time everything works fine :-)

  • may I ask how do you mean by date was set up a few days in the future? Which date are you talking about? Is it a special meta tag?

For me it is working fine in Java:

    private static final String DO_ACCESS_KEY = "some_access_key";
    private static final String DO_SECRET_KEY = "some_secret_key";
    private static final String BUCKET_ENDPOINT = "fra1.digitaloceanspaces.com";
    private static final String BUCKET_REGION = "fra1";
    private static final String BUCKET_NAME = "my-bucket-name";

    public String uploadImageToStorage(byte[] byteimage) {
        AWSCredentialsProvider awscp = new AWSStaticCredentialsProvider(
                new BasicAWSCredentials(DO_ACCESS_KEY, DO_SECRET_KEY));

        AmazonS3 space = AmazonS3ClientBuilder
                .standard()
                .withCredentials(awscp)
                .withEndpointConfiguration(
                        new AwsClientBuilder.EndpointConfiguration(BUCKET_ENDPOINT, BUCKET_REGION))
                .build();

        InputStream is = new ByteArrayInputStream(byteimage);

        ObjectMetadata om = new ObjectMetadata();
        om.setContentLength(byteimage.length);
        om.setContentType("image/jpg");

        String filepath = "images/users/test/testfile.jpg";
        space.putObject(BUCKET_NAME, filepath, is, om);

        return space.getUrl(BUCKET_NAME, filepath).toString();
    }
Have another answer? Share your knowledge.