Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Curl silently fails to upload file to downloads with HTTP/2 401 in the logs

Denis Baltor November 2, 2023

I'm trying to upload a file to my repo's downloads section from my pipeline using curl.

The step doesn't fail but the file is NOT uploaded. We can read HTTP/2 401 in the logs (line 70):

+ curl -v -X POST -u "${BITBUCKET_USERNAME}:${BITBUCKET_APP_PASSWORD}" "https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/downloads" -F files="@dependency-check.tar"
2 Note: Unnecessary use of -X or --request, POST is already inferred.

3 % Total % Received % Xferd Average Speed Time Time Time Current

4 Dload Upload Total Spent Left Speed 

5

6 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 18.205.93.6:443... 

7 * Connected to api.bitbucket.org (18.205.93.6) port 443

8 * ALPN: curl offers h2,http/1.1 

9 } [5 bytes data]

10 * TLSv1.3 (OUT), TLS handshake, Client hello (1):

11 } [512 bytes data]

12 * CAfile: /etc/pki/tls/certs/ca-bundle.crt

13 * CApath: none

14 { [5 bytes data]

15 * TLSv1.3 (IN), TLS handshake, Server hello (2):

16 { [88 bytes data]

17 * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):

18 } [1 bytes data]

19 * TLSv1.3 (OUT), TLS handshake, Client hello (1):

20 } [512 bytes data]

21 * TLSv1.3 (IN), TLS handshake, Server hello (2):

22 { [155 bytes data] 

23 * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):

24 { [15 bytes data]

25 * TLSv1.3 (IN), TLS handshake, Certificate (11):

26 { [2772 bytes data]

27 * TLSv1.3 (IN), TLS handshake, CERT verify (15):

28 { [78 bytes data]

29 * TLSv1.3 (IN), TLS handshake, Finished (20):

30 { [36 bytes data]

31 * TLSv1.3 (OUT), TLS handshake, Finished (20):

32 } [36 bytes data] 

33
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
34 * ALPN: server accepted h2

35 * Server certificate:

36 * subject: C=US; ST=California; L=San Francisco; O=Atlassian US, Inc.; CN=*.bitbucket.org

37 * start date: Apr 28 00:00:00 2023 GMT

38 * expire date: Mar 28 23:59:59 2024 GMT

39 * subjectAltName: host "api.bitbucket.org" matched cert's "*.bitbucket.org"

40 * issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert SHA2 High Assurance Server CA

41
* SSL certificate verify ok.

42 } [5 bytes data]

43 * using HTTP/2

44 * Server auth using Basic with user '<OMMITED>'

45 * [HTTP/2] [1] OPENED stream for https://api.bitbucket.org/2.0/repositories/<OMMITED>/<OMMITED>/downloads

46 * [HTTP/2] [1] [:method: POST]

47 * [HTTP/2] [1] [:scheme: https]

48 * [HTTP/2] [1] [:authority: api.bitbucket.org]

49 * [HTTP/2] [1] [:path: /2.0/repositories/<OMMITED>/<OMMITED>/downloads]

50 * [HTTP/2] [1] [authorization: Basic <OMMITED>]

51 * [HTTP/2] [1] [user-agent: curl/8.3.0]

52 * [HTTP/2] [1] [accept: */*]

53 * [HTTP/2] [1] [content-length: 200315093]

54* [HTTP/2] [1] [content-type: multipart/form-data; boundary=------------------------40685d70a281abee]

55 } [5 bytes data]

56 > POST /2.0/repositories/<OMMITED>/<OMMITED>/downloads HTTP/2

57 > Host: api.bitbucket.org

58 > Authorization: Basic <OMMITED>

59 > User-Agent: curl/8.3.0

60 > Accept: */*

61 > Content-Length: 200315093

62 > Content-Type: multipart/form-data; boundary=------------------------40685d70a281abee

63 >

64 } [5 bytes data]

65 * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):

66 { [202 bytes data]

67

68 51 191M 0 0 51 97.8M 0 231M --:--:-- --:--:-- --:--:-- 231M* We are completely uploaded and fine

69 { [5 bytes data]

70 < HTTP/2 401

71 < server: envoy

72 * Authentication problem. Ignoring this.

73 < www-authenticate: Basic realm="Bitbucket.org HTTP"

74 < vary: Origin

75 < cache-control: max-age=0, no-cache, no-store, must-revalidate

76< content-type: text/plain

77< x-b3-traceid: 213298583d24461f

78< x-usage-output-ops: 0

79< x-dc-location: Micros-3

80< strict-transport-security: max-age=31536000; includeSubDomains; preload

81< date: Thu, 02 Nov 2023 09:45:10 GMT

82< x-request-id: 213298583d24461f

83< x-usage-user-time: 0.010569

84< x-usage-system-time: 0.000000

85< x-served-by: 1734b7da7b86

86
< expires: Thu, 02 Nov 2023 09:45:10 GMT

87< x-xss-protection: 1; mode=block

88< x-envoy-upstream-service-time: 49

89< x-b3-spanid: 8de8f4bddac92b22

90< x-static-version: 0a88acc2851f

91< x-content-type-options: nosniff

92< x-render-time: 0.008195877075195312

93< x-trace-id: 213298583d24461f

94< x-usage-input-ops: 0

95< x-version: 0a88acc2851f

96< x-request-count: 2690

97< x-frame-options: SAMEORIGIN

98< content-length: 0

99<

100

101 100 191M 0 0 100 191M 0 121M 0:00:01 0:00:01 --:--:-- 121M{ [0 bytes data]

102


103 100 191M 0 0 100 191M 0 121M 0:00:01 0:00:01 --:--:-- 121M

104 * Connection #0 to host api.bitbucket.org left intact


The same command works just fine from a local container I built following this guidance. In this case, the logs reads like below:

 

* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* We are completely uploaded and fine
< HTTP/2 201
< server: envoy
 

 

1 answer

0 votes
Theodora Boudale
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
November 6, 2023

Hi Denis and welcome to the community!

A 401 error indicates an issue with the credentials used for authentication.

If you are using the credentials of your own account, please ensure the following:

  • BITBUCKET_USERNAME should be the username of your Bitbucket account and it can be found here https://bitbucket.org/account/settings/. The call won't work if you use your email address or the label of the app password.
  • The app password needs to have at least Repositories - Write permission for the call to succeed. If you don't remember the app password's permissions, you can generate a new one via https://bitbucket.org/account/settings/app-passwords/ and replace the value of BITBUCKET_APP_PASSWORD in Repository settings.
  • The Bitbucket account whose credentials you use for authentication needs to have at least write access to the repo you want to upload the file.

 

You could also use a repository access token instead of username and app password (so you don't store an account's credentials in the variables). The repository access token can be generated from Repository settings > Access tokens of the repo you are uploading to (if you are not an admin, you can ask an admin to generate an access token with Repositories - Write permission).

You can then use a call as follows, where access_token is a repository variable in the repo where the build runs and it holds the value of the repository access token:

curl -v -X POST "https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/downloads" -F files="@dependency-check.tar" --header "Authorization:Bearer ${access_token}"

Kind regards,
Theodora

Denis Baltor November 10, 2023

Hi Theodora,
Thank you very much for reaching out. I had done all the app password setup you mentioned above but did it again anyway. I seem to have messed the password up when copying it into the pipeline secret. It's working now.

However, I-ll switch to the access token approach. You advice was much appreciated!

Kind regards
Denis

Theodora Boudale
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
November 10, 2023

Hi Denis,

Thank you for the update and you are very welcome!

Please feel free to reach out if you ever need anything else!

Kind regards,
Theodora

Like Denis Baltor likes this

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
CLOUD
TAGS
AUG Leaders

Atlassian Community Events