Question

What is the maximum size for the values in Windows Azure blob metadata?

I can see that the web server will impose a practical upper limit of about 4k.

Was it helpful?

Solution

Max. metadata size is 8K as per the documentation here: https://docs.microsoft.com/en-us/rest/api/storageservices/Setting-and-Retrieving-Properties-and-Metadata-for-Blob-Resources

  • Metadata names must adhere to the naming rules for C# identifiers.
  • Names are case-insensitive but are case-insensitive when set or read.
  • If two or more metadata headers with the same name are submitted for a resource, the Blob service returns status code 400 (Bad Request).
  • The metadata consists of name/value pairs.
  • The total size of all metadata pairs can be up to 8KB in size.
  • Metadata name/value pairs are valid HTTP headers, and so they adhere to all restrictions governing HTTP headers.

Additionally:

Here's a client-side validation check you could use:

static void ValidateMetadata( IEnumerable< KeyValuePair<String,String> > blobMetadata )
{
    const int AZURE_MD_NAME_PREFIX_LENGTH = 10; // "x-ms-meta-"

    Int32 totalLength = 0;
    foreach( KeyValuePair<String,String> md in blobMetadata )
    {
        totalLength += AZURE_MD_NAME_PREFIX_LENGTH + md.Key.Length + m.Value.Length;
        
        if( !IsValidMetadataName( md.Key ) )
        {
            throw new ArgumentException( message: "Metadata name \"" + md.Key + "\" is invalid." );
        }
    
        if( md.Value.Any( c => !IsValidHttpHeaderValueChar( c ) ) || md.Value.Contains("\r\n") )
        {
            throw new ArgumentException( message: "Metadata value \"" + md.Value + "\" is invalid." );
        }
    }

    if( totalLength > 8192 )
    {
         throw new ArgumentException( message: "Total length of metadata names and values " + totalLength +" exceeds 8KiB limit." );
    }
}

private static Boolean IsValidMetadataName( String name )
{
    // https://stackoverflow.com/questions/47687379/what-characters-are-allowed-in-http-header-values

    if( String.IsNullOrWhiteSpace( name ) ) return false;

    // The intersection of valid HTTP Header Names and C# Identifiers means:
    // * First character must be a letter.
    // * All other characters must be ASCII letters or digits.
    // * Underscores are technically legal, but many HTTP systems reject them: https://stackoverflow.com/questions/22856136/why-http-servers-forbid-underscores-in-http-header-names - this method disallows underscores to be safe, though in practice it will probably work fine.

    if( !Char.IsLetter( name[0] ) ) return false;
    
    foreach( Char c in name )
    {
        bool validChar = Char.IsLetterOrDigit( c ) && c < 127;
        if( !validChar ) return false;
    }

    return true;
}

private static Boolean IsValidHttpHeaderChar( Char c )
{
    // Technically a quoted-string can contain almost any character ("quoted-string" in the HTTP spec), but it's unclear if Azure Blob storage supports that or not.

    bool isCtl  = ( 0 <= c && c <= 31 ) || ( c == 127 );
    if( isCtl ) return false;
    return true; // This method checks individual chars, so it cannot check for \r\n.
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top