GoogleCloudPlatform / GoogleCloudPlatform/gsutil

gsutil setmeta does not clear Content-Disposition

Open
#1,886 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
918
Forks
335
PR merge metrics
No merged PRs in 30d

Description

It makes two HEAD requests, but never PUT request.

```
gsutil -DD setmeta -h "Content-Disposition" gs://bucket/header.txt
***************************** WARNING *****************************
*** You are running gsutil with debug output enabled.
*** Be aware that debug output includes authentication credentials.
*** Make sure to remove the value of the Authorization header for
*** each HTTP request printed to the console prior to posting to
*** a public medium such as a forum post or Stack Overflow.
***************************** WARNING *****************************
gsutil version: 5.35
checksum: 463ae9998133cda1b7d55035f3d5e7b9 (OK)
boto version: 2.49.0
python version: 3.12.10 (main, Apr 25 2025, 21:39:22) [Clang 20.1.0 ]
OS: Linux 6.8.0-86-generic
multiprocessing available: True
using cloud sdk: True
pass cloud sdk credentials to gsutil: True
config path(s): /root/.boto
gsutil path: /usr/lib/google-cloud-sdk/bin/gsutil
compiled crcmod: True
installed via package manager: False
editable install: False
shim enabled: False
Command being run: /usr/lib/google-cloud-sdk/platform/gsutil/gsutil -o GSUtil:default_project_id=prj1 -o Boto:https_validate_certificates=False -o Boto:ca_certificates_file=/etc/red/certs/root.crt -DD setmeta -h Content-Disposition gs://bucket/header.txt
config_file_list: ['/root/.boto']
config: [('working_dir', '/mnt/pyami'), ('debug', '0'), ('num_retries', '3'), ('ca_certificates_file', '/etc/red/certs/root.crt'), ('https_validate_certificates', 'False'), ('working_dir', '/mnt/pyami'), ('debug', '0'), ('default_project_id', 'prj1'), ('default_region', 'US'), ('resumable_threshold', '629145600'), ('parallel_process_count', '2'), ('parallel_thread_count', '10'), ('parallel_composite_upload_threshold', '0'), ('parallel_composite_upload_component_size', '1000M'), ('sliced_object_download_threshold', '524288'), ('sliced_object_download_component_size', '524288'), ('sliced_object_download_max_components', '3'), ('content_language', 'en'), ('json_api_version', 'v1'), ('prefer_api', 'xml'), ('default_api_version', '1')]
DEBUG 1029 00:50:17.318360 provider.py] Using access key found in config file.
DEBUG 1029 00:50:17.318497 provider.py] Using secret key found in config file.
DEBUG 1029 00:50:17.318927 connection.py] path=/bucket/header.txt
DEBUG 1029 00:50:17.318997 connection.py] auth_path=/bucket/header.txt
DEBUG 1029 00:50:17.319160 connection.py] Method: HEAD
DEBUG 1029 00:50:17.319204 connection.py] Path: /bucket/header.txt
DEBUG 1029 00:50:17.319228 connection.py] Data:
DEBUG 1029 00:50:17.319247 connection.py] Headers: {'x-goog-api-version': '1'}
DEBUG 1029 00:50:17.319262 connection.py] Host: redt.my.com:8021
DEBUG 1029 00:50:17.319277 connection.py] Port: 8021
DEBUG 1029 00:50:17.319290 connection.py] Params: {}
DEBUG 1029 00:50:17.319342 connection.py] establishing HTTPS connection: host=redt.my.com, kwargs={'timeout': 70, 'port': 8021}
DEBUG 1029 00:50:17.319874 connection.py] Token: None
DEBUG 1029 00:50:17.319990 auth.py] StringToSign:
HEAD
Wed, 29 Oct 2025 00:50:17 GMT
x-goog-api-version:1
/bucket/header.txt
DEBUG 1029 00:50:17.320060 auth.py] Signature:
GOOG1 TFRIBVU6UELM9KKZGZ9P:nrLRasNfVPKl/yf3c3lHElrUf7Q=
DEBUG 1029 00:50:17.320093 connection.py] Final headers: {'x-goog-api-version': '1', 'User-Agent': 'Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/945b61ef3c4749aab9439ec93ac75be6 command/setmeta google-cloud-sdk/537.0.0', 'Date': 'Wed, 29 Oct 2025 00:50:17 GMT', 'Authorization': 'GOOG1 TFRIBVU6UELM9KKZGZ9P:nrLRasNfVPKl/yf3c3lHElrUf7Q=', 'Content-Length': '0'}
send: b'HEAD /bucket/header.txt HTTP/1.1\r\nHost: redt.my.com:8021\r\nAccept-Encoding: identity\r\nx-goog-api-version: 1\r\nUser-Agent: Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/945b61ef3c4749aab9439ec93ac75be6 command/setmeta google-cloud-sdk/537.0.0\r\nDate: Wed, 29 Oct 2025 00:50:17 GMT\r\nAuthorization: GOOG1 TFRIBVU6UELM9KKZGZ9P:nrLRasNfVPKl/yf3c3lHElrUf7Q=\r\nContent-Length: 0\r\n\r\n'
Zero length chunk ignored
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Length: 12
header: Date: Wed, 29 Oct 2025 00:50:17 GMT
header: Last-Modified: Wed, 29 Oct 2025 00:43:46 GMT
header: Cache-Control: public, max-age=3600
header: Content-Disposition: inline
header: Content-Encoding: identity
header: Content-Language: en
header: Content-Type: text/html
header: x-amz-tagging-count: 0
header: ETag: "8fac2894018e7be8d026aa7151192b91"
header: x-goog-generation: 18446744073709551615
header: x-goog-metageneration: 1
header: x-goog-storage-class: STANDARD
header: x-goog-stored-content-encoding: identity
header: Accept-Ranges: bytes
header: Connection: keep-alive
header: x-amz-request-id: 510000000035
DEBUG 1029 00:50:17.332889 connection.py] Response headers: [('Content-Length', '12'), ('Date', 'Wed, 29 Oct 2025 00:50:17 GMT'), ('Last-Modified', 'Wed, 29 Oct 2025 00:43:46 GMT'), ('Cache-Control', 'public, max-age=3600'), ('Content-Disposition', 'inline'), ('Content-Encoding', 'identity'), ('Content-Language', 'en'), ('Content-Type', 'text/html'), ('x-amz-tagging-count', '0'), ('ETag', '"8fac2894018e7be8d026aa7151192b91"'), ('x-goog-generation', '18446744073709551615'), ('x-goog-metageneration', '1'), ('x-goog-storage-class', 'STANDARD'), ('x-goog-stored-content-encoding', 'identity'), ('Accept-Ranges', 'bytes'), ('Connection', 'keep-alive'), ('x-amz-request-id', '510000000035')]
process count: 1
thread count: 1
Setting metadata on gs://bucket/header.txt...
DEBUG 1029 00:50:17.374858 connection.py] path=/bucket/header.txt
DEBUG 1029 00:50:17.374932 connection.py] auth_path=/bucket/header.txt
DEBUG 1029 00:50:17.374978 connection.py] Method: HEAD
DEBUG 1029 00:50:17.374999 connection.py] Path: /bucket/header.txt
DEBUG 1029 00:50:17.375014 connection.py] Data:
DEBUG 1029 00:50:17.375031 connection.py] Headers: {'x-goog-api-version': '1'}
DEBUG 1029 00:50:17.375046 connection.py] Host: redt.my.com:8021
DEBUG 1029 00:50:17.375062 connection.py] Port: 8021
DEBUG 1029 00:50:17.375076 connection.py] Params: {}
DEBUG 1029 00:50:17.375153 connection.py] Token: None
DEBUG 1029 00:50:17.375215 auth.py] StringToSign:
HEAD
Wed, 29 Oct 2025 00:50:17 GMT
x-goog-api-version:1
/bucket/header.txt
DEBUG 1029 00:50:17.375265 auth.py] Signature:
GOOG1 TFRIBVU6UELM9KKZGZ9P:nrLRasNfVPKl/yf3c3lHElrUf7Q=
DEBUG 1029 00:50:17.375290 connection.py] Final headers: {'x-goog-api-version': '1', 'User-Agent': 'Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/945b61ef3c4749aab9439ec93ac75be6 command/setmeta google-cloud-sdk/537.0.0', 'Date': 'Wed, 29 Oct 2025 00:50:17 GMT', 'Authorization': 'GOOG1 TFRIBVU6UELM9KKZGZ9P:nrLRasNfVPKl/yf3c3lHElrUf7Q=', 'Content-Length': '0'}
send: b'HEAD /bucket/header.txt HTTP/1.1\r\nHost: redt.my.com:8021\r\nAccept-Encoding: identity\r\nx-goog-api-version: 1\r\nUser-Agent: Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/945b61ef3c4749aab9439ec93ac75be6 command/setmeta google-cloud-sdk/537.0.0\r\nDate: Wed, 29 Oct 2025 00:50:17 GMT\r\nAuthorization: GOOG1 TFRIBVU6UELM9KKZGZ9P:nrLRasNfVPKl/yf3c3lHElrUf7Q=\r\nContent-Length: 0\r\n\r\n'
Zero length chunk ignored
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Length: 12
header: Date: Wed, 29 Oct 2025 00:50:17 GMT
header: Last-Modified: Wed, 29 Oct 2025 00:43:46 GMT
header: Cache-Control: public, max-age=3600
header: Content-Disposition: inline
header: Content-Encoding: identity
header: Content-Language: en
header: Content-Type: text/html
header: x-amz-tagging-count: 0
header: ETag: "8fac2894018e7be8d026aa7151192b91"
header: x-goog-generation: 18446744073709551615
header: x-goog-metageneration: 1
header: x-goog-storage-class: STANDARD
header: x-goog-stored-content-encoding: identity
header: Accept-Ranges: bytes
header: Connection: keep-alive
header: x-amz-request-id: 510000000036
DEBUG 1029 00:50:17.380430 connection.py] Response headers: [('Content-Length', '12'), ('Date', 'Wed, 29 Oct 2025 00:50:17 GMT'), ('Last-Modified', 'Wed, 29 Oct 2025 00:43:46 GMT'), ('Cache-Control', 'public, max-age=3600'), ('Content-Disposition', 'inline'), ('Content-Encoding', 'identity'), ('Content-Language', 'en'), ('Content-Type', 'text/html'), ('x-amz-tagging-count', '0'), ('ETag', '"8fac2894018e7be8d026aa7151192b91"'), ('x-goog-generation', '18446744073709551615'), ('x-goog-metageneration', '1'), ('x-goog-storage-class', 'STANDARD'), ('x-goog-stored-content-encoding', 'identity'), ('Accept-Ranges', 'bytes'), ('Connection', 'keep-alive'), ('x-amz-request-id', '510000000036')]
/ [1 objects]
Operation completed over 1 objects.

```
If we use two headers, the first has value and the second is empty, gsutil overrides empty header from HEAD response

send: b'PUT /bucket/header.txt HTTP/1.1\r\nHost: redt.my.com:8021\r\nAccept-Encoding: identity\r\nx-goog-api-version: 1\r\nx-goog-if-generation-match: 18446744073709551615\r\nx-goog-if-metageneration-match: 1\r\nx-goog-copy-source: bucket/header.txt\r\nx-goog-storage-class: STANDARD\r\nx-goog-metadata-directive: REPLACE\r\ncontent-type: text/html\r\ncontent-language: en\r\ncache-control: public, max-age=3600\r\ncontent-encoding: identity\r\n**content-disposition: inline**\r\nUser-Agent: Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/76854ace95c9428b9637cb03040cd871 command/setmeta google-cloud-sdk/537.0.0\r\nDate: Wed, 29 Oct 2025 00:43:46 GMT\r\nAuthorization: GOOG1 TFRIBVU6UELM9KKZGZ9P:8hdKKW2SqZ7TfRI7VLONZG6Dz7g=\r\nContent-Length: 0\r\n\r\n'

Full log

```
gsutil -DD setmeta -h "Content-Type:text/html" -h "Content-Disposition" gs://bucket/header.txt
***************************** WARNING *****************************
*** You are running gsutil with debug output enabled.
*** Be aware that debug output includes authentication credentials.
*** Make sure to remove the value of the Authorization header for
*** each HTTP request printed to the console prior to posting to
*** a public medium such as a forum post or Stack Overflow.
***************************** WARNING *****************************
gsutil version: 5.35
checksum: 27746065e6ec52b6a38409907fd40076 (!= 463ae9998133cda1b7d55035f3d5e7b9)
boto version: 2.49.0
python version: 3.12.10 (main, Apr 25 2025, 21:39:22) [Clang 20.1.0 ]
OS: Linux 6.8.0-86-generic
multiprocessing available: True
using cloud sdk: True
pass cloud sdk credentials to gsutil: True
config path(s): /root/.boto
gsutil path: /usr/lib/google-cloud-sdk/bin/gsutil
compiled crcmod: True
installed via package manager: False
editable install: False
shim enabled: False
Command being run: /usr/lib/google-cloud-sdk/platform/gsutil/gsutil -o GSUtil:default_project_id=prj1 -o Boto:https_validate_certificates=False -o Boto:ca_certificates_file=/etc/red/certs/root.crt -DD setmeta -h Content-Type:text/html -h Content-Disposition gs://bucket/header.txt
config_file_list: ['/root/.boto']
config: [('working_dir', '/mnt/pyami'), ('debug', '0'), ('num_retries', '3'), ('ca_certificates_file', '/etc/red/certs/root.crt'), ('https_validate_certificates', 'False'), ('working_dir', '/mnt/pyami'), ('debug', '0'), ('default_project_id', 'prj1'), ('default_region', 'US'), ('resumable_threshold', '629145600'), ('parallel_process_count', '2'), ('parallel_thread_count', '10'), ('parallel_composite_upload_threshold', '0'), ('parallel_composite_upload_component_size', '1000M'), ('sliced_object_download_threshold', '524288'), ('sliced_object_download_component_size', '524288'), ('sliced_object_download_max_components', '3'), ('content_language', 'en'), ('json_api_version', 'v1'), ('prefer_api', 'xml'), ('default_api_version', '1')]
DEBUG 1029 00:43:46.434238 provider.py] Using access key found in config file.
DEBUG 1029 00:43:46.434397 provider.py] Using secret key found in config file.
DEBUG 1029 00:43:46.434867 connection.py] path=/bucket/header.txt
DEBUG 1029 00:43:46.434959 connection.py] auth_path=/bucket/header.txt
DEBUG 1029 00:43:46.435145 connection.py] Method: HEAD
DEBUG 1029 00:43:46.435193 connection.py] Path: /bucket/header.txt
DEBUG 1029 00:43:46.435230 connection.py] Data:
DEBUG 1029 00:43:46.435271 connection.py] Headers: {'x-goog-api-version': '1'}
DEBUG 1029 00:43:46.435306 connection.py] Host: redt.my.com:8021
DEBUG 1029 00:43:46.435340 connection.py] Port: 8021
DEBUG 1029 00:43:46.435373 connection.py] Params: {}
DEBUG 1029 00:43:46.435454 connection.py] establishing HTTPS connection: host=redt.my.com, kwargs={'timeout': 70, 'port': 8021}
DEBUG 1029 00:43:46.436057 connection.py] Token: None
DEBUG 1029 00:43:46.436209 auth.py] StringToSign:
HEAD
Wed, 29 Oct 2025 00:43:46 GMT
x-goog-api-version:1
/bucket/header.txt
DEBUG 1029 00:43:46.436335 auth.py] Signature:
GOOG1 TFRIBVU6UELM9KKZGZ9P:Oi7vRtoWk2dbXG2YHCzRVyzYKd8=
DEBUG 1029 00:43:46.436389 connection.py] Final headers: {'x-goog-api-version': '1', 'User-Agent': 'Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/76854ace95c9428b9637cb03040cd871 command/setmeta google-cloud-sdk/537.0.0', 'Date': 'Wed, 29 Oct 2025 00:43:46 GMT', 'Authorization': 'GOOG1 TFRIBVU6UELM9KKZGZ9P:Oi7vRtoWk2dbXG2YHCzRVyzYKd8=', 'Content-Length': '0'}
send: b'HEAD /bucket/header.txt HTTP/1.1\r\nHost: redt.my.com:8021\r\nAccept-Encoding: identity\r\nx-goog-api-version: 1\r\nUser-Agent: Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/76854ace95c9428b9637cb03040cd871 command/setmeta google-cloud-sdk/537.0.0\r\nDate: Wed, 29 Oct 2025 00:43:46 GMT\r\nAuthorization: GOOG1 TFRIBVU6UELM9KKZGZ9P:Oi7vRtoWk2dbXG2YHCzRVyzYKd8=\r\nContent-Length: 0\r\n\r\n'
Zero length chunk ignored
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Length: 12
header: Date: Wed, 29 Oct 2025 00:43:46 GMT
header: Last-Modified: Wed, 29 Oct 2025 00:43:39 GMT
header: Cache-Control: public, max-age=3600
header: Content-Disposition: inline
header: Content-Encoding: identity
header: Content-Language: en
header: Content-Type: text/html
header: x-amz-tagging-count: 0
header: ETag: "8fac2894018e7be8d026aa7151192b91"
header: x-goog-generation: 18446744073709551615
header: x-goog-metageneration: 1
header: x-goog-storage-class: STANDARD
header: x-goog-stored-content-encoding: identity
header: Accept-Ranges: bytes
header: Connection: keep-alive
header: x-amz-request-id: 510000000027
DEBUG 1029 00:43:46.447174 connection.py] Response headers: [('Content-Length', '12'), ('Date', 'Wed, 29 Oct 2025 00:43:46 GMT'), ('Last-Modified', 'Wed, 29 Oct 2025 00:43:39 GMT'), ('Cache-Control', 'public, max-age=3600'), ('Content-Disposition', 'inline'), ('Content-Encoding', 'identity'), ('Content-Language', 'en'), ('Content-Type', 'text/html'), ('x-amz-tagging-count', '0'), ('ETag', '"8fac2894018e7be8d026aa7151192b91"'), ('x-goog-generation', '18446744073709551615'), ('x-goog-metageneration', '1'), ('x-goog-storage-class', 'STANDARD'), ('x-goog-stored-content-encoding', 'identity'), ('Accept-Ranges', 'bytes'), ('Connection', 'keep-alive'), ('x-amz-request-id', '510000000027')]
process count: 1
thread count: 1
Setting metadata on gs://bucket/header.txt...
DEBUG 1029 00:43:46.491314 connection.py] path=/bucket/header.txt
DEBUG 1029 00:43:46.491400 connection.py] auth_path=/bucket/header.txt
DEBUG 1029 00:43:46.491466 connection.py] Method: HEAD
DEBUG 1029 00:43:46.491511 connection.py] Path: /bucket/header.txt
DEBUG 1029 00:43:46.491549 connection.py] Data:
DEBUG 1029 00:43:46.491584 connection.py] Headers: {}
DEBUG 1029 00:43:46.491620 connection.py] Host: redt.my.com:8021
DEBUG 1029 00:43:46.491656 connection.py] Port: 8021
DEBUG 1029 00:43:46.491690 connection.py] Params: {}
DEBUG 1029 00:43:46.491795 connection.py] Token: None
DEBUG 1029 00:43:46.491880 auth.py] StringToSign:
HEAD
Wed, 29 Oct 2025 00:43:46 GMT
/bucket/header.txt
DEBUG 1029 00:43:46.491976 auth.py] Signature:
GOOG1 TFRIBVU6UELM9KKZGZ9P:rWaEsEeICAVCpmLdzCcVpsXeYvM=
DEBUG 1029 00:43:46.492024 connection.py] Final headers: {'User-Agent': 'Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/76854ace95c9428b9637cb03040cd871 command/setmeta google-cloud-sdk/537.0.0', 'Date': 'Wed, 29 Oct 2025 00:43:46 GMT', 'Authorization': 'GOOG1 TFRIBVU6UELM9KKZGZ9P:rWaEsEeICAVCpmLdzCcVpsXeYvM=', 'Content-Length': '0'}
send: b'HEAD /bucket/header.txt HTTP/1.1\r\nHost: redt.my.com:8021\r\nAccept-Encoding: identity\r\nUser-Agent: Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/76854ace95c9428b9637cb03040cd871 command/setmeta google-cloud-sdk/537.0.0\r\nDate: Wed, 29 Oct 2025 00:43:46 GMT\r\nAuthorization: GOOG1 TFRIBVU6UELM9KKZGZ9P:rWaEsEeICAVCpmLdzCcVpsXeYvM=\r\nContent-Length: 0\r\n\r\n'
Zero length chunk ignored
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Length: 12
header: Date: Wed, 29 Oct 2025 00:43:46 GMT
header: Last-Modified: Wed, 29 Oct 2025 00:43:39 GMT
header: Cache-Control: public, max-age=3600
header: Content-Disposition: inline
header: Content-Encoding: identity
header: Content-Language: en
header: Content-Type: text/html
header: x-amz-tagging-count: 0
header: ETag: "8fac2894018e7be8d026aa7151192b91"
header: x-goog-generation: 18446744073709551615
header: x-goog-metageneration: 1
header: x-goog-storage-class: STANDARD
header: x-goog-stored-content-encoding: identity
header: Accept-Ranges: bytes
header: Connection: keep-alive
header: x-amz-request-id: 510000000028
DEBUG 1029 00:43:46.499778 connection.py] Response headers: [('Content-Length', '12'), ('Date', 'Wed, 29 Oct 2025 00:43:46 GMT'), ('Last-Modified', 'Wed, 29 Oct 2025 00:43:39 GMT'), ('Cache-Control', 'public, max-age=3600'), ('Content-Disposition', 'inline'), ('Content-Encoding', 'identity'), ('Content-Language', 'en'), ('Content-Type', 'text/html'), ('x-amz-tagging-count', '0'), ('ETag', '"8fac2894018e7be8d026aa7151192b91"'), ('x-goog-generation', '18446744073709551615'), ('x-goog-metageneration', '1'), ('x-goog-storage-class', 'STANDARD'), ('x-goog-stored-content-encoding', 'identity'), ('Accept-Ranges', 'bytes'), ('Connection', 'keep-alive'), ('x-amz-request-id', '510000000028')]
DEBUG 1029 00:43:46.500023 connection.py] path=/bucket/header.txt
DEBUG 1029 00:43:46.500077 connection.py] auth_path=/bucket/header.txt
DEBUG 1029 00:43:46.500136 connection.py] Method: PUT
DEBUG 1029 00:43:46.500171 connection.py] Path: /bucket/header.txt
DEBUG 1029 00:43:46.500207 connection.py] Data:
DEBUG 1029 00:43:46.500247 connection.py] Headers: {'x-goog-api-version': '1', 'x-goog-if-generation-match': '18446744073709551615', 'x-goog-if-metageneration-match': '1', 'x-goog-copy-source': 'bucket/header.txt', 'x-goog-storage-class': 'STANDARD', 'x-goog-metadata-directive': 'REPLACE', 'content-type': 'text/html', 'content-language': 'en', 'cache-control': 'public, max-age=3600', 'content-encoding': 'identity', 'content-disposition': 'inline'}
DEBUG 1029 00:43:46.500282 connection.py] Host: redt.my.com:8021
DEBUG 1029 00:43:46.500314 connection.py] Port: 8021
DEBUG 1029 00:43:46.500351 connection.py] Params: {}
DEBUG 1029 00:43:46.500438 connection.py] Token: None
DEBUG 1029 00:43:46.500522 auth.py] StringToSign:
PUT
text/html
Wed, 29 Oct 2025 00:43:46 GMT
x-goog-api-version:1
x-goog-copy-source:bucket/header.txt
x-goog-if-generation-match:18446744073709551615
x-goog-if-metageneration-match:1
x-goog-metadata-directive:REPLACE
x-goog-storage-class:STANDARD
/bucket/header.txt
DEBUG 1029 00:43:46.500632 auth.py] Signature:
GOOG1 TFRIBVU6UELM9KKZGZ9P:8hdKKW2SqZ7TfRI7VLONZG6Dz7g=
DEBUG 1029 00:43:46.500683 connection.py] Final headers: {'x-goog-api-version': '1', 'x-goog-if-generation-match': '18446744073709551615', 'x-goog-if-metageneration-match': '1', 'x-goog-copy-source': 'bucket/header.txt', 'x-goog-storage-class': 'STANDARD', 'x-goog-metadata-directive': 'REPLACE', 'content-type': 'text/html', 'content-language': 'en', 'cache-control': 'public, max-age=3600', 'content-encoding': 'identity', 'content-disposition': 'inline', 'User-Agent': 'Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/76854ace95c9428b9637cb03040cd871 command/setmeta google-cloud-sdk/537.0.0', 'Date': 'Wed, 29 Oct 2025 00:43:46 GMT', 'Authorization': 'GOOG1 TFRIBVU6UELM9KKZGZ9P:8hdKKW2SqZ7TfRI7VLONZG6Dz7g=', 'Content-Length': '0'}
send: b'PUT /bucket/header.txt HTTP/1.1\r\nHost: redt.my.com:8021\r\nAccept-Encoding: identity\r\nx-goog-api-version: 1\r\nx-goog-if-generation-match: 18446744073709551615\r\nx-goog-if-metageneration-match: 1\r\nx-goog-copy-source: bucket/header.txt\r\nx-goog-storage-class: STANDARD\r\nx-goog-metadata-directive: REPLACE\r\ncontent-type: text/html\r\ncontent-language: en\r\ncache-control: public, max-age=3600\r\ncontent-encoding: identity\r\ncontent-disposition: inline\r\nUser-Agent: Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/76854ace95c9428b9637cb03040cd871 command/setmeta google-cloud-sdk/537.0.0\r\nDate: Wed, 29 Oct 2025 00:43:46 GMT\r\nAuthorization: GOOG1 TFRIBVU6UELM9KKZGZ9P:8hdKKW2SqZ7TfRI7VLONZG6Dz7g=\r\nContent-Length: 0\r\n\r\n'
Zero length chunk ignored
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Length: 187
header: Date: Wed, 29 Oct 2025 00:43:46 GMT
header: x-amz-copy-source-version-id: LygHa16AHYF
header: x-goog-generation: 9223372036854775807
header: x-goog-metageneration: 1
header: Connection: keep-alive
header: x-amz-request-id: 510000000029
DEBUG 1029 00:43:46.514482 connection.py] Response headers: [('Content-Length', '187'), ('Date', 'Wed, 29 Oct 2025 00:43:46 GMT'), ('x-amz-copy-source-version-id', 'LygHa16AHYF'), ('x-goog-generation', '9223372036854775807'), ('x-goog-metageneration', '1'), ('Connection', 'keep-alive'), ('x-amz-request-id', '510000000029')]
DEBUG 1029 00:43:46.516011 connection.py] path=/bucket/header.txt
DEBUG 1029 00:43:46.516107 connection.py] auth_path=/bucket/header.txt
DEBUG 1029 00:43:46.516188 connection.py] Method: HEAD
DEBUG 1029 00:43:46.516235 connection.py] Path: /bucket/header.txt
DEBUG 1029 00:43:46.516276 connection.py] Data:
DEBUG 1029 00:43:46.516320 connection.py] Headers: {'x-goog-api-version': '1'}
DEBUG 1029 00:43:46.516363 connection.py] Host: redt.my.com:8021
DEBUG 1029 00:43:46.516405 connection.py] Port: 8021
DEBUG 1029 00:43:46.516446 connection.py] Params: {}
DEBUG 1029 00:43:46.516553 connection.py] Token: None
DEBUG 1029 00:43:46.516643 auth.py] StringToSign:
HEAD
Wed, 29 Oct 2025 00:43:46 GMT
x-goog-api-version:1
/bucket/header.txt
DEBUG 1029 00:43:46.516759 auth.py] Signature:
GOOG1 TFRIBVU6UELM9KKZGZ9P:Oi7vRtoWk2dbXG2YHCzRVyzYKd8=
DEBUG 1029 00:43:46.516820 connection.py] Final headers: {'x-goog-api-version': '1', 'User-Agent': 'Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/76854ace95c9428b9637cb03040cd871 command/setmeta google-cloud-sdk/537.0.0', 'Date': 'Wed, 29 Oct 2025 00:43:46 GMT', 'Authorization': 'GOOG1 TFRIBVU6UELM9KKZGZ9P:Oi7vRtoWk2dbXG2YHCzRVyzYKd8=', 'Content-Length': '0'}
send: b'HEAD /bucket/header.txt HTTP/1.1\r\nHost: redt.my.com:8021\r\nAccept-Encoding: identity\r\nx-goog-api-version: 1\r\nUser-Agent: Boto/2.49.0 Python/3.12.10 Linux/6.8.0-86-generic gsutil/5.35 (linux) analytics/disabled interactive/True invocation-id/76854ace95c9428b9637cb03040cd871 command/setmeta google-cloud-sdk/537.0.0\r\nDate: Wed, 29 Oct 2025 00:43:46 GMT\r\nAuthorization: GOOG1 TFRIBVU6UELM9KKZGZ9P:Oi7vRtoWk2dbXG2YHCzRVyzYKd8=\r\nContent-Length: 0\r\n\r\n'
Zero length chunk ignored
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Length: 12
header: Date: Wed, 29 Oct 2025 00:43:46 GMT
header: Last-Modified: Wed, 29 Oct 2025 00:43:46 GMT
header: Cache-Control: public, max-age=3600
header: Content-Disposition: inline
header: Content-Encoding: identity
header: Content-Language: en
header: Content-Type: text/html
header: x-amz-tagging-count: 0
header: ETag: "8fac2894018e7be8d026aa7151192b91"
header: x-goog-generation: 18446744073709551615
header: x-goog-metageneration: 1
header: x-goog-storage-class: STANDARD
header: x-goog-stored-content-encoding: identity
header: Accept-Ranges: bytes
header: Connection: keep-alive
header: x-amz-request-id: 510000000030
DEBUG 1029 00:43:46.518659 connection.py] Response headers: [('Content-Length', '12'), ('Date', 'Wed, 29 Oct 2025 00:43:46 GMT'), ('Last-Modified', 'Wed, 29 Oct 2025 00:43:46 GMT'), ('Cache-Control', 'public, max-age=3600'), ('Content-Disposition', 'inline'), ('Content-Encoding', 'identity'), ('Content-Language', 'en'), ('Content-Type', 'text/html'), ('x-amz-tagging-count', '0'), ('ETag', '"8fac2894018e7be8d026aa7151192b91"'), ('x-goog-generation', '18446744073709551615'), ('x-goog-metageneration', '1'), ('x-goog-storage-class', 'STANDARD'), ('x-goog-stored-content-encoding', 'identity'), ('Accept-Ranges', 'bytes'), ('Connection', 'keep-alive'), ('x-amz-request-id', '510000000030')]
/ [1 objects]
Operation completed over 1 objects.

```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the issue with the provided gsutil setmeta commands and inspect the setmeta command path that handles metadata replacement. Confirm the fix by verifying that a request with an empty Content-Disposition results in a PUT and removes the existing value, while other metadata remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli, cloud
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.