Every instance has metadata associated with it. Some of this metadata can be defined by the user, and other information, such as the host name, is assigned by Google Compute Engine during the startup process.
Compute Engine might offer more than one metadata version at a single time, but it is recommended that you always use the newest metadata server version available. At any time, Google Compute Engine can add new entries to the metadata server and add new fields to responses. Check back periodically for changes!
Current version: v1
Contents
Metadata server
Every instance stores its metadata on the metadata server. You can query this metadata server programmatically for information such as the instance's host name, instance ID, startup scripts, and custom metadata. It also provides access to service account information. Your instance automatically has access to the metadata server API without any additional authorization.
Metadata is stored in the format
key:value
. There is a default set of metadata
entries that every instance has access to and you can also choose to create
custom metadata
. To query for certain metadata, you can construct a
request to the metadata server using the URL or the IP address.
-
Full URL:
http://metadata.google.internal/computeMetadata/v1/
-
Shorthand URL:
http://metadata/computeMetadata/v1/
-
IP address:
http://169.254.169.254/computeMetadata/v1/
For more information, see querying metadata .
Default metadata
Google Compute Engine defines a set of default metadata entries that provide information about your instance or project. Default metadata is always defined and set by the server. You cannot manually edit any of these metadata pairs.
The following is a list of default metadata available to a project. Some
metadata entries are directories that contain other metadata keys. This
difference is marked by a trailing slash in the metadata name. For example,
attributes/
is a directory that contains other keys, while
numeric-project-id
is a metadata key or endpoint that maps to a value.
Relative to
http://metadata.google.internal/computeMetadata/v1/project/
|
|
---|---|
Metadata Entry | Description |
attributes/
|
A directory of custom metadata values that are passed to the project. |
attributes/sshKeys
|
A list of ssh keys that can be used to connect to instances in the project. |
numeric-project-id
|
The numeric project ID of the instance, which is not the same as the
project name visible in the
Google Developers Console
. Do not use this as the
project with
gcloud compute
;
instead, use the
project-id
metadata entry value.
|
project-id
|
The project ID . |
The following is a list of default metadata available to an instance:
Relative to
http://metadata.google.internal/computeMetadata/v1/instance/
|
|
---|---|
Metadata Entry | Description |
attributes/
|
A directory of custom metadata values passed to the instance during startup. See Specifying Custom Metadata below. |
description
|
The free-text description of an instance, assigned using the
--description
flag, or set in the API.
|
disks/
|
A directory of disks attached to this instance. |
hostname
|
The host name of the instance. |
id
|
The ID of the instance. This is a unique, numerical ID that is generated by Google Compute Engine. This is useful for identifying instances if you do not want to use instance names. |
image
|
The fully-qualified image name. |
machine-type
|
The fully-qualified machine type name of the instance's host machine. |
network-interfaces/
|
A directory of network interfaces for the instance. |
network-interfaces/
<index>
/forwarded-ips/
|
A directory of any external IPs that are currently pointing to this
virtual machine instance, for the network interface at
<index>
. Specifically, provides a list of
external IPs served by
forwarding
rules
that direct packets to this instance.
|
scheduling/
|
A directory with the scheduling options for the instance. |
scheduling/on-host-maintenance
|
The instance's
scheduled maintenance
event behavior
setting. This value is
set
with the
‑‑on_host_maintenance
flag or via the API.
|
scheduling/automatic-restart
|
The instance's
automatic
restart
setting. This value is
set
with the
‑‑automatic_restart
flag or via the API.
|
maintenance-event
|
The path that indicates that a scheduled maintenance event is affecting this instance. See Scheduled maintenance notice for details. |
project-id
|
The instance's project ID. You can use this the project for
gcloud compute
commands.
|
service-accounts/
|
A directory of service accounts associated with the instance. |
tags
|
Any tags associated with the instance. |
zone
|
The instance's zone. |
Querying metadata
You can query a metadata server only from its associated instance. You cannot query an instance's metadata from another instance or directly from your local computer. For example, you would send a curl or wget command from the instance to its metadata server.
You can query the metadata server using the root metadata server URL or the IP address. All of these URLs will work for your metadata requests.
-
Full URL:
http://metadata.google.internal/computeMetadata/v1/
-
Shorthand URL:
http://metadata/computeMetadata/v1/
-
IP address:
http://169.254.169.254/computeMetadata/v1/
These are the root URLs for all instance and project metadata. Specific metadata values are defined as sub-paths below these root URLs.
When you query the metadata server, you must also provide the following header in all of your requests:
Metadata-Flavor: Google
This header indicates that the request was sent with the intention of retrieving metadata values, rather than unintentionally from an insecure source, and allows the metadata server to return the data you requested. If you do not provide this header, the metadata server denies your request.
Depending on the type of query you make, the metadata server can return data in a number of ways.
Querying directory listings
The metadata server uses directories to organize certain metadata keys. Any
metadata entry ending in a trailing slash is a directory. For example, the
disks/
entry is a directory of disks attached to that instance:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/" -H "Metadata-Flavor: Google"
0/
1/
2/
Similarly, if you wanted more information about the
1/
directory, you can
query the specific URL for that directory:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/1/" -H "Metadata-Flavor: Google"
device-name
index
mode
type
Querying metadata endpoints
Other metadata entries are keys or endpoints that return one or more values. To query for data from a metadata endpoint, send a query to that particular endpoint. For example, to query the mode of a specific disk, query the following endpoint:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/1/mode" -H "Metadata-Flavor: Google"
READ_WRITE
By default, each endpoint defines the format for returned data. Some endpoints
might return data in JSON format by default, while other endpoints might return
data as a string. You can override the default data format specification by
using the
alt=json
or
alt=text
query parameters, which returns data in JSON
string format or as a plaintext representation, respectfully.
For example, the
tags
key automatically returns data in JSON format. You
can choose to return data in text format instead, by specifying the
alt=text
query parameter:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags" -H "Metadata-Flavor: Google"
["bread","butter","cheese","cream","lettuce"]
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?alt=text" -H "Metadata-Flavor: Google"
bread
butter
cheese
cream
lettuce
Querying recursive contents
If you want to return all contents underneath a directory, use the
recursive=true
query parameter with your request:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true" -H "Metadata-Flavor: Google"
[{"deviceName":"boot","index":0,"mode":"READ_WRITE","type":"PERSISTENT"},
{"deviceName":"persistent-disk-1","index":1,"mode":"READ_WRITE","type":"PERSISTENT"},
{"deviceName":"persistent-disk-2","index":2,"mode":"READ_ONLY","type":"PERSISTENT"}]
By default, recursive contents are returned in JSON format. If you want to
return these contents in text format, append the
alt=text
query parameter:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true&alt=text" -H "Metadata-Flavor: Google"
0/device-name boot
0/index 0
0/mode READ_WRITE
0/type PERSISTENT
1/device-name persistent-disk-1
1/index 1
1/mode READ_WRITE
1/type PERSISTENT
2/device-name persistent-disk-1
2/index 2
2/mode READ_ONLY
2/type PERSISTENT
Detecting if you are running in Compute Engine
You can easily detect if your applications or scripts are running within a
Compute Engine instance by using the metadata server. When you make a
request to the server, any response from the metadata server will contain the
Metadata-Flavor: Google
header. You can look for this header to
reliably detect if you are running in Compute Engine.
For example, the following curl request returns a
Metadata-Flavor: Google
header, indicating that the request is being made from within a
Compute Engine instance.
me@my-inst:~$ curl metadata.google.internal -i
HTTP/1.1 200 OK
Metadata-Flavor: Google
Content-Type: application/text
Date: Thu, 10 Apr 2014 19:24:27 GMT
Server: Metadata Server for VM
Content-Length: 22
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
0.1/
computeMetadata/
Specifying custom metadata
You can set custom metadata for an instance or project outside of the server- defined metadata. This is useful for passing in arbitrary values to your project or instance that can be queried by your code on the instance.
When you specify custom metadata, the metadata server stores it in the
attributes/
directory for that instance or project. To query for all the
custom metadata available to an instance or project, query the
attributes/
directory:
curl "http://metadata.google.internal/computeMetadata/v1/<instance|project>/attributes/" -H "Metadata-Flavor: Google"
Setting custom instance metadata
You can set custom metadata for an instance either using the
--metadata
flag
during instance creation, or by using the
gcloud compute add-metadata
method on a running
instance. Setting metadata is additive, so you only need to specify the metadata
keys that you want to add or change. If you specify an existing key, then the
key's value will be updated.
Setting metadata during instance creation
To pass in custom metadata during instance creation, provide the
--metadata
flag with your request. You can provide this flag as many times as you would
like, and pass in multiple metadata pairs. The following example demonstrates
starting a new instance with the key "bread" and the value
"butter", and querying it from the instance.
$ gcloud compute instances create myinstance --metadata bread=butter
... select a zone...
Created [https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/myinstance].
NAME ZONE MACHINE_TYPE INTERNAL_IP EXTERNAL_IP STATUS
myinstance us-central1-a n1-standard-1 10.240.231.222 23.236.48.97 RUNNING ...
$ gcloud compute ssh myinstance
user@myinstance:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/bread" -H "Metadata-Flavor: Google"
butter
Updating or setting metadata on a running instance
If you want to set or update the metadata entries for a running instance, you
can use the
instances add-metadata
command:
$ gcloud compute instances add-metadata INSTANCE --metadata key-1=value-1 key-2=value-2 key-n=value-n
Because metadata updates are additive, you need to specify only the metadata keys that you want to add or change. If you specify an existing key, then the key's value will be updated with the new value. For example, assume your instance metadata looks like this:
metadata:
fingerprint: _OW8mWFLqsk=
items:
- key: bread
value: mayo
- key: cheese
value: cheddar
- key: lettuce
value: butter
If you want to change the
lettuce=butter
entry to
lettuce=green
, use:
$ gcloud compute instances add-metadata INSTANCE --metadata lettuce=green
If you want to remove the
lettuce=butter
entry, use:
$ gcloud compute instances remove-metadata INSTANCE --keys lettuce
Applying a startup script using custom metadata
The custom metadata option is especially useful for specifying startup scripts
that run during instance boot. Startup scripts can be used to install software,
check and start services, or set custom environment variables. With
gcloud compute
, you can pass in startup scripts using the
--metadata
flag or from a local file using the
--metadata-from-file
flag.
The
--metadata-from-file
flag is useful for passing in in script content that
is too large to pass in with the
--metadata
flag.
In images that have the Cloud SDK installed on them, the metadata keys
startup-script
and
startup-script-url
are reserved for passing in script-
related metadata.
For example:
-
Passing in a startup script from a local file:
gcloud compute instances create example-instance --metadata-from-file startup-script=FILE
-
Passing in a startup script from Google Cloud Storage:
gcloud compute instances create example-instance --metadata startup-script-url=URL
-
Passing in your startup script directly:
gcloud compute instances create example-instance --metadata startup-script="#! /bin/bash > # Installs apache and a custom homepage > apt-get update > apt-get install -y apache2 > cat <<EOF > /var/www/index.html > <html><body><h1>Hello World</h1> > <p>This page was created from a simple start up script!</p> > </body></html> > EOF"
For more information about startup scripts and how to use them, see Using Startup Scripts .
Setting project-wide custom metadata
If you want to set project-level custom metadata, which is accessible by all
instances in that project, you can do so using the
add-metadata
command. For example, if you define a project-wide metadata pair of
baz=bat
,
the metadata pair is automatically available to all instances at the
project/attributes/
directory:
http://metadata.google.internal/computeMetadata/v1/project/attributes/
To set project-wide metadata using
gcloud compute
, use the
project-info add-metadata
command. For example:
$ gcloud compute project-info add-metadata --metadata foo=bar baz=bat
$ gcloud compute project-info describe
...
commonInstanceMetadata:
fingerprint: RfOFY_-eS64=
items:
- key: baz
value: bat
- key: foo
value: bar
- key: sshKeys
...
One metadata key-value pair is specified with an equals sign, for example,
key=value
. Multiple key-value pairs are separated with spaces.
You can optionally specify one or more files from which to read metadata using
the
--metadata-from-file
flag.
Updating project-wide metadata
Similar to instance metadata, project metadata updates are additive. This means that you need to only specify the metadata keys that you want to add or change. If you specify an existing key, then the key's value will be updated with the new value. For example, assume you have the following metadata entries:
commonInstanceMetadata:
fingerprint: PceRYYVzGbo8=
items:
- key: baz
value: bat
- key: foo
value: bar
- key: try
value: eat
- key: car
value: saw
If you wanted to update the metadata value for
baz
and
foo
, then you need
to only specify those keys in the
gcloud compute
command.
$ gcloud compute project-info add-metadata --metadata baz=new foo=new
If you're updating metadata that might be several strings long, you might want
to use the
--metadata-from-file
flag, which reads in the contents
of a file as the key value:
$ gcloud compute project-info add-metadata --metadata-from-file KEY=FILE
This is especially useful for setting metadata attributes like sshKeys, which is
usually a random combination of several strings. Rather than providing the raw
string value, you could just save the string in the file and provide the file
with the
--metadata-from-file
flag.
Waiting for change
Given that metadata values can change while your instance is running, the
metadata server offers the ability to be notified of metadata changes using the
wait-for-change feature. This feature allows you to perform hanging
HTTP GET
requests that only return when your specified metadata has changed. You can use
this feature on custom metadata or server-defined metadata, so if anything
changes about your instance or project, or if someone updates a custom metadata,
you can programmatically react to the change. For example, you can perform a
request on the
tags
key so that the request only returns if the contents of
the tags metadata has changed. When the request returns, it provides the new
value of that metadata key.
To perform a wait-for-change request, query a metadata key and append the
?wait_for_change=true
query parameter:
user$myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true" -H "Metadata-Flavor: Google"
After there is a change to the specified metadata key, the query returns with the new value. In this example, if a request is made to the setInstanceTags method, the request returns with the new values:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true" -H "Metadata-Flavor: Google"
cheese
lettuce
You can also perform a wait-for-change request recursively on the contents of a directory:
user$myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&wait_for_change=true" -H "Metadata-Flavor: Google"
The metadata server returns the new contents if there is any change:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&wait_for_change=true" -H "Metadata-Flavor: Google"
{"cheese":"lettuce","cookies":"cream"}
The wait-for-change feature also lets you match with your request and set timeouts .
Using ETags
If you submit a simple wait-for-change query, the metadata server returns if
anything has changed in the contents of that metadata. However, there is an
inherent race condition between a metadata update and a wait-for-change request
being issued, so it is useful to have a reliable way to know you are getting the
latest metadata value. To help with this, you can use the
last_etag
query
parameter, which compares the ETag value you provide with the ETag value saved
on the metadata server. If the ETag values match, then the wait-for-change
request will be accepted. If the ETag values do not match, this indicates that
the contents of the metadata has changed since the last time you retrieved the
ETag value, and the metadata server returns immediately with this latest value.
To grab the current ETag value for a metadata key, make a request to that key
and print the headers. In CURL, you can do this with the
-v
flag:
user@myinst:~$ curl -v "http://metadata.google.internal/computeMetadata/v1/instance/tags" -H "Metadata-Flavor: Google" * About to connect() to metadata port 80 (#0) * Trying 169.254.169.254... connected * Connected to metadata (169.254.169.254) port 80 (#0) > GET /computeMetadata/v1/instance/tags?wait_for_change=true HTTP/1.1 > User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15 > Host: metadata > Accept: */* > < HTTP/1.1 200 OK < Content-Type: application/text < ETag: 411261ca6c9e654e < Date: Wed, 13 Feb 2013 22:43:45 GMT < Server: Metadata Server for VM < Content-Length: 26 < X-XSS-Protection: 1; mode=block < X-Frame-Options: SAMEORIGIN < cheese lettuce
You can also grab the ETag programmatically. The following example uses Python to extract the ETag value from the metadata response:
import httplib2
def main():
http = httplib2.Http()
response, content = http.request('http://metadata.google.internal/computeMetadata/v1/instance/tags',
headers={'Metadata-Flavor': 'True'})
etag = response['etag']
print etag
if __name__ == '__main__':
main()
Use that ETag value in your wait-for-change request:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&last_etag=411261ca6c9e654e" -H "Metadata-Flavor: Google"
The metadata server will match your specified ETag value and if that value changes, the request returns with the new contents of your metadata key.
Using 0 As Your ETag Value
The metadata server will never return 0 as an ETag. You could use that information to simplify some of your code. For example, the following code example sets the initial ETag value as 0, performs a request to the server, which immediately returns with the initial data and the current ETag value, and then uses that information to wait for a change. This method would save you from writing additional lines of code to grab the first initial ETag.
import httplib2 METADATA_URL = 'http://metadata.google.internal/computeMetadata/v1/' def main(): http = httplib2.Http() tagsUrl = METADATA_URL + 'instance/tags?wait_for_change=true' # set the first last_etag as 0 last_etag = 0 while True: # returns immediately on the initial request because 0 is invalid # otherwise wait until something changes resp,content = http.request(uri=tagsUrl + '&last_etag=' + str(last_etag), method='GET', body='', headers={'Metadata-Flavor': 'True'}) if resp != 500: last_etag = resp['etag'] print content if __name__ == '__main__': main()
Setting timeouts
If you would like your wait-for-change request to time out after a certain
number of seconds, you can set the
timeout_sec=<timeout-in-seconds>
query
parameter. The
timeout_sec
parameter limits the wait time of your request to
the number of seconds you specified and when the request reaches that limit, it
returns the current contents of the metadata key. Here is an example of a
wait-for-change request that is set to time out after 360 seconds:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&timeout_sec=360" -H "Metadata-Flavor: Google"
When you set the
timeout_sec
parameter, the request always returns after the
specified number of seconds, whether or not the metadata value has actually
changed. It is only possible to set an integer value for your timeout.
Status codes
When you perform a wait-for-change request, the metadata server returns standard HTTP status codes to indicate success or failure. In the case of errors, network conditions can cause the metadata server to fail your request and return an error code. In these cases, you should design your application to be fault-tolerant and to be able to recognize and handle these errors.
The possible statuses that the metadata server returns are:
Status | Description |
---|---|
HTTP 200
|
Success! A value was changed, or you reached your specified
timeout_sec
and the request
returned successfully.
|
Error 400
|
Your request was invalid. Please fix your query and retry the request. |
Error 404
|
The metadata value you specified no longer exists. The metadata server also returns this error if your metadata is deleted while you are waiting on a change. |
Error 500
|
There was a temporary server error. Please retry your request. |
Scheduled maintenance notice
The metadata server provides information about an instance's scheduling
options and settings, through the
scheduling/
directory and the
maintenance-event
attribute. You can use these attributes to learn
about a virtual machine instance's scheduling options, and also use this
information to notify you when a maintenance event is about to happen,
specifically through the
maintenance-event
attribute.
The
maintenance-event
attribute changes its value to indicate the start and
end of a maintenance event. The initial value of the attribute is
NONE
, which
indicates that no maintenance event is starting. 60 seconds before a scheduled
maintenance event, the
maintenance-event
value changes from
NONE
to
MIGRATE_ON_HOST_MAINTENANCE
. Throughout the duration of the maintenance event,
the value remains the same. After the maintenance event ends, the value returns
to
NONE
.
To query the
maintenance-event
attribute:
user@myinst:~$ curl http://metadata.google.internal/computeMetadata/v1/instance/maintenance-event
NONE
You can use the
maintenance-event
with the
waiting for change
feature to notify your scripts and
applications when a maintenance event is about to start and end. This lets you
automate any actions that you might want to run before or after the event. The
following Python sample provides an example of how you might implement these two
features together.
import httplib
import sys
import time
import urllib
import urllib2
METADATA_URL = 'http://metadata.google.internal/computeMetadata/v1/'
class Error(Exception):
pass
class UnexpectedStatusException(Error):
pass
class UnexpectedMaintenanceEventException(Error):
pass
def WatchMetadata(metadata_key, handler, initial_value=None):
"""Watches for a change in the value of metadata.
Args:
metadata_key: The key identifying which metadata to watch for changes.
handler: A callable to call when the metadata value changes. Will be passed
a single parameter, the new value of the metadata.
initial_value: The expected initial value for the metadata. The handler will
not be called on the initial metadata request unless the value differs
from this.
Raises:
UnexpectedStatusException: If the http request is unsuccessful for an
unexpected reason.
"""
params = {
'wait_for_change': 'true',
'last_etag': 0,
}
while True:
value = initial_value
# start a hanging-GET request for maintenance change events.
url = '{base_url}{key}?{params}'.format(
base_url=METADATA_URL,
key=metadata_key,
params=urllib.urlencode(params)
)
req = urllib2.Request(url, headers={'Metadata-Flavor': 'Google'})
try:
response = urllib2.urlopen(req)
content = response.read()
status = response.getcode()
except urllib2.HTTPError as e:
content = None
status = e.code
if status == httplib.SERVICE_UNAVAILABLE:
time.sleep(1)
continue
elif status == httplib.OK:
# Extract new maintenance-event value and latest etag.
new_value = content
headers = response.info()
params['last_etag'] = headers['ETag']
else:
raise UnexpectedStatusException(status)
# If the maintenance value changed, call the appropriate handler.
if value != new_value:
value = new_value
handler(value)
def HandleMaintenance(on_maintenance_start, on_maintenance_end):
"""Watches for and responds to maintenance-event status changes.
Args:
on_maintenance_start: a callable to call before host maintenance starts.
on_maintenance_end: a callable to call after host maintenance ends.
Raises:
UnexpectedStatusException: If the http request is unsuccessful for an
unexpected reason.
UnexpectedMaintenanceEventException: If the maintenance-event value is
not either NONE or MIGRATE_ON_HOST_MAINTENANCE.
Note: Instances that are set to TERMINATE_ON_HOST_MAINTENANCE will receive
a power-button push and will not be notified through this script.
"""
maintenance_key = 'instance/maintenance-event'
def Handler(event):
if event == 'MIGRATE_ON_HOST_MAINTENANCE':
on_maintenance_start()
elif event == 'NONE':
on_maintenance_end()
else:
raise UnexpectedMaintenanceEventException(event)
WatchMetadata(maintenance_key, Handler, initial_value='NONE')
def OnMaintenanceStart():
# Add commands to perform before maintenance starts here.
pass
def OnMaintenanceEnd():
# Add commands to perform after maintenance is complete here.
pass
if __name__ == '__main__':
# Perform actions when maintenance events occur.
HandleMaintenance(OnMaintenanceStart, OnMaintenanceEnd)
# An example of watching for changes in a different metadata field.
# Replace 'foo' with an existing custom metadata key of your choice.
#
# WatchMetadata('instance/attributes/foo',
# lambda val: sys.stdout.write('%s\n' % val))
Transitioning to v1
The v1 metadata server functions slightly differently that the previous v1beta1 server. Here are some of the changes that need to be made for the new metadata server:
-
Update metadata requests to include the
Metadata-Flavor: Google
headerThe new metadata server requires that all requests provide the
Metadata-Flavor: Google
header, which indicates that the request was made with the intention of retrieving metadata values, Update your requests to include this new header. For example, a request to thedisks/
attribute now looks like the following:user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/" -H "Metadata-Flavor: Google"
-
Update requests that use the header
X-Forwarded-For
headerThese requests are automatically rejected by the server, as it generally indicates that the requests are proxied. Update your requests so they do not contain this header.