github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/gateway/errors/errors.go (about)

     1  package errors
     2  
     3  import (
     4  	"encoding/xml"
     5  	"net/http"
     6  )
     7  
     8  /*
     9   * TAKEN FROM THE MinIO project and adapted for embedding in Versio
    10   *
    11   * MinIO Cloud Storage, (C) 2015, 2016, 2017, 2018 MinIO, Inc.
    12   *
    13   * Licensed under the Apache License, Version 2.0 (the "License");
    14   * you may not use this file except in compliance with the License.
    15   * You may obtain a copy of the License at
    16   *
    17   *     http://www.apache.org/licenses/LICENSE-2.0
    18   *
    19   * Unless required by applicable law or agreed to in writing, software
    20   * distributed under the License is distributed on an "AS IS" BASIS,
    21   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    22   * See the License for the specific language governing permissions and
    23   * limitations under the License.
    24   */
    25  
    26  // APIError structure
    27  type APIError struct {
    28  	Code           string
    29  	Description    string
    30  	HTTPStatusCode int
    31  }
    32  
    33  // APIErrorResponse - error response format
    34  type APIErrorResponse struct {
    35  	XMLName    xml.Name `xml:"Error" json:"-"`
    36  	Code       string
    37  	Message    string
    38  	Key        string `xml:"Key,omitempty" json:"Key,omitempty"`
    39  	BucketName string `xml:"BucketName,omitempty" json:"BucketName,omitempty"`
    40  	Resource   string
    41  	Region     string `xml:"Region,omitempty" json:"Region,omitempty"`
    42  	RequestID  string `xml:"RequestId" json:"RequestId"`
    43  	HostID     string `xml:"HostId" json:"HostId"`
    44  }
    45  
    46  // APIErrorCode type of error status.
    47  type APIErrorCode int
    48  
    49  // Error codes, non exhaustive list - https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
    50  const (
    51  	ErrNone APIErrorCode = iota
    52  	ErrAccessDenied
    53  	ErrBadDigest
    54  	ErrEntityTooSmall
    55  	ErrEntityTooLarge
    56  	ErrPolicyTooLarge
    57  	ErrIncompleteBody
    58  	ErrInternalError
    59  	ErrInvalidAccessKeyID
    60  	ErrInvalidBucketName
    61  	ErrInvalidDigest
    62  	ErrInvalidRange
    63  	ErrInvalidCopyPartRange
    64  	ErrInvalidCopyPartRangeSource
    65  	ErrInvalidMaxKeys
    66  	ErrInvalidEncodingMethod
    67  	ErrInvalidMaxUploads
    68  	ErrInvalidMaxParts
    69  	ErrInvalidPartNumberMarker
    70  	ErrInvalidRequestBody
    71  	ErrInvalidCopySource
    72  	ErrInvalidMetadataDirective
    73  	ErrInvalidCopyDest
    74  	ErrInvalidPolicyDocument
    75  	ErrInvalidObjectState
    76  	ErrMalformedXML
    77  	ErrMissingContentLength
    78  	ErrMissingContentMD5
    79  	ErrMissingRequestBodyError
    80  	ErrNoSuchBucket
    81  	ErrNoSuchBucketPolicy
    82  	ErrNoSuchBucketLifecycle
    83  	ErrNoSuchKey
    84  	ErrNoSuchUpload
    85  	ErrNoSuchVersion
    86  	ErrNotImplemented
    87  	ErrPreconditionFailed
    88  	ErrRequestTimeTooSkewed
    89  	ErrSignatureDoesNotMatch
    90  	ErrMethodNotAllowed
    91  	ErrInvalidPart
    92  	ErrInvalidPartOrder
    93  	ErrAuthorizationHeaderMalformed
    94  	ErrMalformedPOSTRequest
    95  	ErrPOSTFileRequired
    96  	ErrSignatureVersionNotSupported
    97  	ErrBucketNotEmpty
    98  	ErrAllAccessDisabled
    99  	ErrMalformedPolicy
   100  	ErrMissingFields
   101  	ErrMissingCredTag
   102  	ErrCredMalformed
   103  	ErrInvalidRegion
   104  	ErrInvalidService
   105  	ErrInvalidRequestVersion
   106  	ErrMissingSignTag
   107  	ErrMissingSignHeadersTag
   108  	ErrMalformedDate
   109  	ErrMalformedPresignedDate
   110  	ErrMalformedCredentialDate
   111  	ErrMalformedCredentialRegion
   112  	ErrMalformedExpires
   113  	ErrNegativeExpires
   114  	ErrAuthHeaderEmpty
   115  	ErrExpiredPresignRequest
   116  	ErrRequestNotReadyYet
   117  	ErrUnsignedHeaders
   118  	ErrMissingDateHeader
   119  	ErrInvalidQuerySignatureAlgo
   120  	ErrInvalidQueryParams
   121  	ErrBucketAlreadyOwnedByYou
   122  	ErrInvalidDuration
   123  	ErrBucketAlreadyExists
   124  	ErrMetadataTooLarge
   125  	ErrUnsupportedMetadata
   126  	ErrMaximumExpires
   127  	ErrSlowDown
   128  	ErrInvalidPrefixMarker
   129  	ErrBadRequest
   130  	ErrKeyTooLongError
   131  	ErrInvalidAPIVersion
   132  	// Add new error codes here.
   133  
   134  	// SSE-S3 related API errors
   135  	ErrInvalidEncryptionMethod
   136  
   137  	// Server-Side-Encryption (with Customer provided key) related API errors.
   138  	ErrInsecureSSECustomerRequest
   139  	ErrSSEMultipartEncrypted
   140  	ErrSSEEncryptedObject
   141  	ErrInvalidEncryptionParameters
   142  	ErrInvalidSSECustomerAlgorithm
   143  	ErrInvalidSSECustomerKey
   144  	ErrMissingSSECustomerKey
   145  	ErrMissingSSECustomerKeyMD5
   146  	ErrSSECustomerKeyMD5Mismatch
   147  	ErrInvalidSSECustomerParameters
   148  	ErrIncompatibleEncryptionMethod
   149  	ErrKMSNotConfigured
   150  	ErrKMSAuthFailure
   151  
   152  	ErrNoAccessKey
   153  	ErrInvalidToken
   154  
   155  	// Bucket notification related errors.
   156  	ErrEventNotification
   157  	ErrARNNotification
   158  	ErrRegionNotification
   159  	ErrOverlappingFilterNotification
   160  	ErrFilterNameInvalid
   161  	ErrFilterNamePrefix
   162  	ErrFilterNameSuffix
   163  	ErrFilterValueInvalid
   164  	ErrOverlappingConfigs
   165  	ErrUnsupportedNotification
   166  
   167  	// S3 extended errors.
   168  	ErrContentSHA256Mismatch
   169  
   170  	// Lakefs errors
   171  	ERRLakeFSNotSupported
   172  	ERRLakeFSWrongEndpoint
   173  	ErrWriteToProtectedBranch
   174  	ErrReadOnlyRepository
   175  )
   176  
   177  type errorCodeMap map[APIErrorCode]APIError
   178  
   179  func (e errorCodeMap) ToAPIErr(errCode APIErrorCode) APIError {
   180  	apiErr, ok := e[errCode]
   181  	if !ok {
   182  		return e[ErrInternalError]
   183  	}
   184  	return apiErr
   185  }
   186  
   187  func (e errorCodeMap) ToAPIErrWithInternalError(errCode APIErrorCode, err error) APIError {
   188  	apiErr := e.ToAPIErr(errCode)
   189  	apiErr.Description = err.Error()
   190  	return apiErr
   191  }
   192  
   193  func (a APIErrorCode) Error() string {
   194  	return Codes.ToAPIErr(a).Code
   195  }
   196  
   197  func (a APIErrorCode) ToAPIErr() APIError {
   198  	return Codes.ToAPIErr(a)
   199  }
   200  
   201  // Codes - error code to APIError structure, these fields carry respective
   202  // descriptions for all the error responses.
   203  var Codes = errorCodeMap{
   204  	ErrInvalidCopyDest: {
   205  		Code:           "InvalidRequest",
   206  		Description:    "This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.",
   207  		HTTPStatusCode: http.StatusBadRequest,
   208  	},
   209  	ErrInvalidCopySource: {
   210  		Code:           "InvalidArgument",
   211  		Description:    "Copy Source must mention the source bucket and key: sourcebucket/sourcekey.",
   212  		HTTPStatusCode: http.StatusBadRequest,
   213  	},
   214  	ErrInvalidMetadataDirective: {
   215  		Code:           "InvalidArgument",
   216  		Description:    "Unknown metadata directive.",
   217  		HTTPStatusCode: http.StatusBadRequest,
   218  	},
   219  	ErrInvalidRequestBody: {
   220  		Code:           "InvalidArgument",
   221  		Description:    "Body shouldn't be set for this request.",
   222  		HTTPStatusCode: http.StatusBadRequest,
   223  	},
   224  	ErrInvalidMaxUploads: {
   225  		Code:           "InvalidArgument",
   226  		Description:    "Argument max-uploads must be an integer between 0 and 2147483647",
   227  		HTTPStatusCode: http.StatusBadRequest,
   228  	},
   229  	ErrInvalidMaxKeys: {
   230  		Code:           "InvalidArgument",
   231  		Description:    "Argument maxKeys must be an integer between 0 and 2147483647",
   232  		HTTPStatusCode: http.StatusBadRequest,
   233  	},
   234  	ErrInvalidEncodingMethod: {
   235  		Code:           "InvalidArgument",
   236  		Description:    "Invalid Encoding Method specified in Request",
   237  		HTTPStatusCode: http.StatusBadRequest,
   238  	},
   239  	ErrInvalidMaxParts: {
   240  		Code:           "InvalidArgument",
   241  		Description:    "Argument max-parts must be an integer between 0 and 2147483647",
   242  		HTTPStatusCode: http.StatusBadRequest,
   243  	},
   244  	ErrInvalidPartNumberMarker: {
   245  		Code:           "InvalidArgument",
   246  		Description:    "Argument partNumberMarker must be an integer.",
   247  		HTTPStatusCode: http.StatusBadRequest,
   248  	},
   249  	ErrInvalidPolicyDocument: {
   250  		Code:           "InvalidPolicyDocument",
   251  		Description:    "The content of the form does not meet the conditions specified in the policy document.",
   252  		HTTPStatusCode: http.StatusBadRequest,
   253  	},
   254  	ErrAccessDenied: {
   255  		Code:           "AccessDenied",
   256  		Description:    "Access Denied.",
   257  		HTTPStatusCode: http.StatusForbidden,
   258  	},
   259  	ErrBadDigest: {
   260  		Code:           "BadDigest",
   261  		Description:    "The Content-Md5 you specified did not match what we received.",
   262  		HTTPStatusCode: http.StatusBadRequest,
   263  	},
   264  	ErrEntityTooSmall: {
   265  		Code:           "EntityTooSmall",
   266  		Description:    "Your proposed upload is smaller than the minimum allowed object size.",
   267  		HTTPStatusCode: http.StatusBadRequest,
   268  	},
   269  	ErrEntityTooLarge: {
   270  		Code:           "EntityTooLarge",
   271  		Description:    "Your proposed upload exceeds the maximum allowed object size.",
   272  		HTTPStatusCode: http.StatusBadRequest,
   273  	},
   274  	ErrPolicyTooLarge: {
   275  		Code:           "PolicyTooLarge",
   276  		Description:    "Policy exceeds the maximum allowed document size.",
   277  		HTTPStatusCode: http.StatusBadRequest,
   278  	},
   279  	ErrIncompleteBody: {
   280  		Code:           "IncompleteBody",
   281  		Description:    "You did not provide the number of bytes specified by the Content-Length HTTP header.",
   282  		HTTPStatusCode: http.StatusBadRequest,
   283  	},
   284  	ErrInternalError: {
   285  		Code:           "InternalError",
   286  		Description:    "We encountered an internal error, please try again.",
   287  		HTTPStatusCode: http.StatusInternalServerError,
   288  	},
   289  	ErrInvalidAccessKeyID: {
   290  		Code:           "InvalidAccessKeyId",
   291  		Description:    "The access key ID you provided does not exist in our records.",
   292  		HTTPStatusCode: http.StatusForbidden,
   293  	},
   294  	ErrInvalidBucketName: {
   295  		Code:           "InvalidBucketName",
   296  		Description:    "The specified bucket is not valid.",
   297  		HTTPStatusCode: http.StatusBadRequest,
   298  	},
   299  	ErrInvalidDigest: {
   300  		Code:           "InvalidDigest",
   301  		Description:    "The Content-Md5 you specified is not valid.",
   302  		HTTPStatusCode: http.StatusBadRequest,
   303  	},
   304  	ErrInvalidRange: {
   305  		Code:           "InvalidRange",
   306  		Description:    "The requested range is not satisfiable",
   307  		HTTPStatusCode: http.StatusRequestedRangeNotSatisfiable,
   308  	},
   309  	ErrMalformedXML: {
   310  		Code:           "MalformedXML",
   311  		Description:    "The XML you provided was not well-formed or did not validate against our published schema.",
   312  		HTTPStatusCode: http.StatusBadRequest,
   313  	},
   314  	ErrMissingContentLength: {
   315  		Code:           "MissingContentLength",
   316  		Description:    "You must provide the Content-Length HTTP header.",
   317  		HTTPStatusCode: http.StatusLengthRequired,
   318  	},
   319  	ErrMissingContentMD5: {
   320  		Code:           "MissingContentMD5",
   321  		Description:    "Missing required header for this request: Content-Md5.",
   322  		HTTPStatusCode: http.StatusBadRequest,
   323  	},
   324  	ErrMissingRequestBodyError: {
   325  		Code:           "MissingRequestBodyError",
   326  		Description:    "Request body is empty.",
   327  		HTTPStatusCode: http.StatusLengthRequired,
   328  	},
   329  	ErrNoSuchBucket: {
   330  		Code:           "NoSuchBucket",
   331  		Description:    "The specified bucket does not exist",
   332  		HTTPStatusCode: http.StatusNotFound,
   333  	},
   334  	ErrNoSuchBucketPolicy: {
   335  		Code:           "NoSuchBucketPolicy",
   336  		Description:    "The bucket policy does not exist",
   337  		HTTPStatusCode: http.StatusNotFound,
   338  	},
   339  	ErrNoSuchBucketLifecycle: {
   340  		Code:           "NoSuchBucketLifecycle",
   341  		Description:    "The bucket lifecycle configuration does not exist",
   342  		HTTPStatusCode: http.StatusNotFound,
   343  	},
   344  	ErrNoSuchKey: {
   345  		Code:           "NoSuchKey",
   346  		Description:    "The specified key does not exist.",
   347  		HTTPStatusCode: http.StatusNotFound,
   348  	},
   349  	ErrNoSuchUpload: {
   350  		Code:           "NoSuchUpload",
   351  		Description:    "The specified multipart upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.",
   352  		HTTPStatusCode: http.StatusNotFound,
   353  	},
   354  	ErrNoSuchVersion: {
   355  		Code:           "NoSuchVersion",
   356  		Description:    "Indicates that the version ID specified in the request does not match an existing version.",
   357  		HTTPStatusCode: http.StatusNotFound,
   358  	},
   359  	ErrNotImplemented: {
   360  		Code:           "NotImplemented",
   361  		Description:    "A header you provided implies functionality that is not implemented",
   362  		HTTPStatusCode: http.StatusNotImplemented,
   363  	},
   364  	ErrPreconditionFailed: {
   365  		Code:           "PreconditionFailed",
   366  		Description:    "At least one of the pre-conditions you specified did not hold",
   367  		HTTPStatusCode: http.StatusPreconditionFailed,
   368  	},
   369  	ErrRequestTimeTooSkewed: {
   370  		Code:           "RequestTimeTooSkewed",
   371  		Description:    "The difference between the request time and the server's time is too large.",
   372  		HTTPStatusCode: http.StatusForbidden,
   373  	},
   374  	ErrSignatureDoesNotMatch: {
   375  		Code:           "SignatureDoesNotMatch",
   376  		Description:    "The request signature we calculated does not match the signature you provided. Check your key and signing method.",
   377  		HTTPStatusCode: http.StatusForbidden,
   378  	},
   379  	ErrMethodNotAllowed: {
   380  		Code:           "MethodNotAllowed",
   381  		Description:    "The specified method is not allowed against this resource.",
   382  		HTTPStatusCode: http.StatusMethodNotAllowed,
   383  	},
   384  	ErrInvalidPart: {
   385  		Code:           "InvalidPart",
   386  		Description:    "One or more of the specified parts could not be found.  The part may not have been uploaded, or the specified entity tag may not match the part's entity tag.",
   387  		HTTPStatusCode: http.StatusBadRequest,
   388  	},
   389  	ErrInvalidPartOrder: {
   390  		Code:           "InvalidPartOrder",
   391  		Description:    "The list of parts was not in ascending order. The parts list must be specified in order by part number.",
   392  		HTTPStatusCode: http.StatusBadRequest,
   393  	},
   394  	ErrInvalidObjectState: {
   395  		Code:           "InvalidObjectState",
   396  		Description:    "The operation is not valid for the current state of the object.",
   397  		HTTPStatusCode: http.StatusForbidden,
   398  	},
   399  	ErrAuthorizationHeaderMalformed: {
   400  		Code:           "AuthorizationHeaderMalformed",
   401  		Description:    "The authorization header is malformed; the region is wrong; expecting 'us-east-1'.",
   402  		HTTPStatusCode: http.StatusBadRequest,
   403  	},
   404  	ErrMalformedPOSTRequest: {
   405  		Code:           "MalformedPOSTRequest",
   406  		Description:    "The body of your POST request is not well-formed multipart/form-data.",
   407  		HTTPStatusCode: http.StatusBadRequest,
   408  	},
   409  	ErrPOSTFileRequired: {
   410  		Code:           "InvalidArgument",
   411  		Description:    "POST requires exactly one file upload per request.",
   412  		HTTPStatusCode: http.StatusBadRequest,
   413  	},
   414  	ErrSignatureVersionNotSupported: {
   415  		Code:           "InvalidRequest",
   416  		Description:    "The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.",
   417  		HTTPStatusCode: http.StatusBadRequest,
   418  	},
   419  	ErrBucketNotEmpty: {
   420  		Code:           "BucketNotEmpty",
   421  		Description:    "The bucket you tried to delete is not empty",
   422  		HTTPStatusCode: http.StatusConflict,
   423  	},
   424  	ErrBucketAlreadyExists: {
   425  		Code:           "BucketAlreadyExists",
   426  		Description:    "The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.",
   427  		HTTPStatusCode: http.StatusConflict,
   428  	},
   429  	ErrAllAccessDisabled: {
   430  		Code:           "AllAccessDisabled",
   431  		Description:    "All access to this bucket has been disabled.",
   432  		HTTPStatusCode: http.StatusForbidden,
   433  	},
   434  	ErrMalformedPolicy: {
   435  		Code:           "MalformedPolicy",
   436  		Description:    "Policy has invalid resource.",
   437  		HTTPStatusCode: http.StatusBadRequest,
   438  	},
   439  	ErrMissingFields: {
   440  		Code:           "MissingFields",
   441  		Description:    "Missing fields in request.",
   442  		HTTPStatusCode: http.StatusBadRequest,
   443  	},
   444  	ErrMissingCredTag: {
   445  		Code:           "InvalidRequest",
   446  		Description:    "Missing Credential field for this request.",
   447  		HTTPStatusCode: http.StatusBadRequest,
   448  	},
   449  	ErrCredMalformed: {
   450  		Code:           "AuthorizationQueryParametersError",
   451  		Description:    "Error parsing the X-Amz-Credential parameter; the Credential is mal-formed; expecting \"<YOUR-AKID>/YYYYMMDD/REGION/SERVICE/aws4_request\".",
   452  		HTTPStatusCode: http.StatusBadRequest,
   453  	},
   454  	ErrMalformedDate: {
   455  		Code:           "MalformedDate",
   456  		Description:    "Invalid date format header, expected to be in ISO8601, RFC1123 or RFC1123Z time format.",
   457  		HTTPStatusCode: http.StatusBadRequest,
   458  	},
   459  	ErrMalformedPresignedDate: {
   460  		Code:           "AuthorizationQueryParametersError",
   461  		Description:    "X-Amz-Date must be in the ISO8601 Long Format \"yyyyMMdd'T'HHmmss'Z'\"",
   462  		HTTPStatusCode: http.StatusBadRequest,
   463  	},
   464  	// FIXME: Should contain the invalid param set as seen in https://github.com/minio/minio/issues/2385.
   465  	// right Description:    "Error parsing the X-Amz-Credential parameter; incorrect date format \"%s\". This date in the credential must be in the format \"yyyyMMdd\".",
   466  	// Need changes to make sure variable messages can be constructed.
   467  	ErrMalformedCredentialDate: {
   468  		Code:           "AuthorizationQueryParametersError",
   469  		Description:    "Error parsing the X-Amz-Credential parameter; incorrect date format \"%s\". This date in the credential must be in the format \"yyyyMMdd\".",
   470  		HTTPStatusCode: http.StatusBadRequest,
   471  	},
   472  	// FIXME: Should contain the invalid param set as seen in https://github.com/minio/minio/issues/2385.
   473  	// right Description:    "Error parsing the X-Amz-Credential parameter; the region 'us-east-' is wrong; expecting 'us-east-1'".
   474  	// Need changes to make sure variable messages can be constructed.
   475  	ErrMalformedCredentialRegion: {
   476  		Code:           "AuthorizationQueryParametersError",
   477  		Description:    "Error parsing the X-Amz-Credential parameter; the region is wrong;",
   478  		HTTPStatusCode: http.StatusBadRequest,
   479  	},
   480  	ErrInvalidRegion: {
   481  		Code:           "InvalidRegion",
   482  		Description:    "Region does not match.",
   483  		HTTPStatusCode: http.StatusBadRequest,
   484  	},
   485  	// FIXME: Should contain the invalid param set as seen in https://github.com/minio/minio/issues/2385.
   486  	// right Description:   "Error parsing the X-Amz-Credential parameter; incorrect service \"s4\". This endpoint belongs to \"s3\".".
   487  	// Need changes to make sure variable messages can be constructed.
   488  	ErrInvalidService: {
   489  		Code:           "AuthorizationQueryParametersError",
   490  		Description:    "Error parsing the X-Amz-Credential parameter; incorrect service. This endpoint belongs to \"s3\".",
   491  		HTTPStatusCode: http.StatusBadRequest,
   492  	},
   493  	// FIXME: Should contain the invalid param set as seen in https://github.com/minio/minio/issues/2385.
   494  	// Description:   "Error parsing the X-Amz-Credential parameter; incorrect terminal "aws4_reque". This endpoint uses "aws4_request".
   495  	// Need changes to make sure variable messages can be constructed.
   496  	ErrInvalidRequestVersion: {
   497  		Code:           "AuthorizationQueryParametersError",
   498  		Description:    "Error parsing the X-Amz-Credential parameter; incorrect terminal. This endpoint uses \"aws4_request\".",
   499  		HTTPStatusCode: http.StatusBadRequest,
   500  	},
   501  	ErrMissingSignTag: {
   502  		Code:           "AccessDenied",
   503  		Description:    "Signature header missing Signature field.",
   504  		HTTPStatusCode: http.StatusBadRequest,
   505  	},
   506  	ErrMissingSignHeadersTag: {
   507  		Code:           "InvalidArgument",
   508  		Description:    "Signature header missing SignedHeaders field.",
   509  		HTTPStatusCode: http.StatusBadRequest,
   510  	},
   511  	ErrMalformedExpires: {
   512  		Code:           "AuthorizationQueryParametersError",
   513  		Description:    "X-Amz-Expires should be a number",
   514  		HTTPStatusCode: http.StatusBadRequest,
   515  	},
   516  	ErrNegativeExpires: {
   517  		Code:           "AuthorizationQueryParametersError",
   518  		Description:    "X-Amz-Expires must be non-negative",
   519  		HTTPStatusCode: http.StatusBadRequest,
   520  	},
   521  	ErrAuthHeaderEmpty: {
   522  		Code:           "InvalidArgument",
   523  		Description:    "Authorization header is invalid -- one and only one ' ' (space) required.",
   524  		HTTPStatusCode: http.StatusBadRequest,
   525  	},
   526  	ErrMissingDateHeader: {
   527  		Code:           "AccessDenied",
   528  		Description:    "AWS authentication requires a valid Date or x-amz-date header",
   529  		HTTPStatusCode: http.StatusBadRequest,
   530  	},
   531  	ErrInvalidQuerySignatureAlgo: {
   532  		Code:           "AuthorizationQueryParametersError",
   533  		Description:    "X-Amz-Algorithm only supports \"AWS4-HMAC-SHA256\".",
   534  		HTTPStatusCode: http.StatusBadRequest,
   535  	},
   536  	ErrExpiredPresignRequest: {
   537  		Code:           "AccessDenied",
   538  		Description:    "Request has expired",
   539  		HTTPStatusCode: http.StatusForbidden,
   540  	},
   541  	ErrRequestNotReadyYet: {
   542  		Code:           "AccessDenied",
   543  		Description:    "Request is not valid yet",
   544  		HTTPStatusCode: http.StatusForbidden,
   545  	},
   546  	ErrSlowDown: {
   547  		Code:           "SlowDown",
   548  		Description:    "Please reduce your request",
   549  		HTTPStatusCode: http.StatusServiceUnavailable,
   550  	},
   551  	ErrInvalidPrefixMarker: {
   552  		Code:           "InvalidPrefixMarker",
   553  		Description:    "Invalid marker prefix combination",
   554  		HTTPStatusCode: http.StatusBadRequest,
   555  	},
   556  	ErrBadRequest: {
   557  		Code:           "BadRequest",
   558  		Description:    "400 BadRequest",
   559  		HTTPStatusCode: http.StatusBadRequest,
   560  	},
   561  	ErrKeyTooLongError: {
   562  		Code:           "KeyTooLongError",
   563  		Description:    "Your key is too long",
   564  		HTTPStatusCode: http.StatusBadRequest,
   565  	},
   566  	// FIXME: Actual XML error response also contains the header which missed in list of signed header parameters.
   567  	ErrUnsignedHeaders: {
   568  		Code:           "AccessDenied",
   569  		Description:    "There were headers present in the request which were not signed",
   570  		HTTPStatusCode: http.StatusBadRequest,
   571  	},
   572  	ErrInvalidQueryParams: {
   573  		Code:           "AuthorizationQueryParametersError",
   574  		Description:    "Query-string authentication version 4 requires the X-Amz-Algorithm, X-Amz-Credential, X-Amz-Signature, X-Amz-Date, X-Amz-SignedHeaders, and X-Amz-Expires parameters.",
   575  		HTTPStatusCode: http.StatusBadRequest,
   576  	},
   577  	ErrBucketAlreadyOwnedByYou: {
   578  		Code:           "BucketAlreadyOwnedByYou",
   579  		Description:    "Your previous request to create the named bucket succeeded and you already own it.",
   580  		HTTPStatusCode: http.StatusConflict,
   581  	},
   582  	ErrInvalidDuration: {
   583  		Code:           "InvalidDuration",
   584  		Description:    "Duration provided in the request is invalid.",
   585  		HTTPStatusCode: http.StatusBadRequest,
   586  	},
   587  
   588  	// Bucket notification related errors.
   589  	ErrEventNotification: {
   590  		Code:           "InvalidArgument",
   591  		Description:    "A specified event is not supported for notifications.",
   592  		HTTPStatusCode: http.StatusBadRequest,
   593  	},
   594  	ErrARNNotification: {
   595  		Code:           "InvalidArgument",
   596  		Description:    "A specified destination ARN does not exist or is not well-formed. Verify the destination ARN.",
   597  		HTTPStatusCode: http.StatusBadRequest,
   598  	},
   599  	ErrRegionNotification: {
   600  		Code:           "InvalidArgument",
   601  		Description:    "A specified destination is in a different region than the bucket. You must use a destination that resides in the same region as the bucket.",
   602  		HTTPStatusCode: http.StatusBadRequest,
   603  	},
   604  	ErrOverlappingFilterNotification: {
   605  		Code:           "InvalidArgument",
   606  		Description:    "An object key name filtering rule defined with overlapping prefixes, overlapping suffixes, or overlapping combinations of prefixes and suffixes for the same event types.",
   607  		HTTPStatusCode: http.StatusBadRequest,
   608  	},
   609  	ErrFilterNameInvalid: {
   610  		Code:           "InvalidArgument",
   611  		Description:    "filter rule name must be either prefix or suffix",
   612  		HTTPStatusCode: http.StatusBadRequest,
   613  	},
   614  	ErrFilterNamePrefix: {
   615  		Code:           "InvalidArgument",
   616  		Description:    "Cannot specify more than one prefix rule in a filter.",
   617  		HTTPStatusCode: http.StatusBadRequest,
   618  	},
   619  	ErrFilterNameSuffix: {
   620  		Code:           "InvalidArgument",
   621  		Description:    "Cannot specify more than one suffix rule in a filter.",
   622  		HTTPStatusCode: http.StatusBadRequest,
   623  	},
   624  	ErrFilterValueInvalid: {
   625  		Code:           "InvalidArgument",
   626  		Description:    "Size of filter rule value cannot exceed 1024 bytes in UTF-8 representation",
   627  		HTTPStatusCode: http.StatusBadRequest,
   628  	},
   629  	ErrOverlappingConfigs: {
   630  		Code:           "InvalidArgument",
   631  		Description:    "Configurations overlap. Configurations on the same bucket cannot share a common event type.",
   632  		HTTPStatusCode: http.StatusBadRequest,
   633  	},
   634  	ErrUnsupportedNotification: {
   635  		Code:           "UnsupportedNotification",
   636  		Description:    "MinIO server does not support Topic or Cloud Function based notifications.",
   637  		HTTPStatusCode: http.StatusBadRequest,
   638  	},
   639  	ErrInvalidCopyPartRange: {
   640  		Code:           "InvalidArgument",
   641  		Description:    "The x-amz-copy-source-range value must be of the form bytes=first-last where first and last are the zero-based offsets of the first and last bytes to copy",
   642  		HTTPStatusCode: http.StatusBadRequest,
   643  	},
   644  	ErrInvalidCopyPartRangeSource: {
   645  		Code:           "InvalidArgument",
   646  		Description:    "Range specified is not valid for source object",
   647  		HTTPStatusCode: http.StatusBadRequest,
   648  	},
   649  	ErrMetadataTooLarge: {
   650  		Code:           "InvalidArgument",
   651  		Description:    "Your metadata headers exceed the maximum allowed metadata size.",
   652  		HTTPStatusCode: http.StatusBadRequest,
   653  	},
   654  	ErrInvalidEncryptionMethod: {
   655  		Code:           "InvalidRequest",
   656  		Description:    "The encryption method specified is not supported",
   657  		HTTPStatusCode: http.StatusBadRequest,
   658  	},
   659  	ErrInsecureSSECustomerRequest: {
   660  		Code:           "InvalidRequest",
   661  		Description:    "Requests specifying Server Side Encryption with Customer provided keys must be made over a secure connection.",
   662  		HTTPStatusCode: http.StatusBadRequest,
   663  	},
   664  	ErrSSEMultipartEncrypted: {
   665  		Code:           "InvalidRequest",
   666  		Description:    "The multipart upload initiate requested encryption. Subsequent part requests must include the appropriate encryption parameters.",
   667  		HTTPStatusCode: http.StatusBadRequest,
   668  	},
   669  	ErrSSEEncryptedObject: {
   670  		Code:           "InvalidRequest",
   671  		Description:    "The object was stored using a form of Server Side Encryption. The correct parameters must be provided to retrieve the object.",
   672  		HTTPStatusCode: http.StatusBadRequest,
   673  	},
   674  	ErrInvalidEncryptionParameters: {
   675  		Code:           "InvalidRequest",
   676  		Description:    "The encryption parameters are not applicable to this object.",
   677  		HTTPStatusCode: http.StatusBadRequest,
   678  	},
   679  	ErrInvalidSSECustomerAlgorithm: {
   680  		Code:           "InvalidArgument",
   681  		Description:    "Requests specifying Server Side Encryption with Customer provided keys must provide a valid encryption algorithm.",
   682  		HTTPStatusCode: http.StatusBadRequest,
   683  	},
   684  	ErrInvalidSSECustomerKey: {
   685  		Code:           "InvalidArgument",
   686  		Description:    "The secret key was invalid for the specified algorithm.",
   687  		HTTPStatusCode: http.StatusBadRequest,
   688  	},
   689  	ErrMissingSSECustomerKey: {
   690  		Code:           "InvalidArgument",
   691  		Description:    "Requests specifying Server Side Encryption with Customer provided keys must provide an appropriate secret key.",
   692  		HTTPStatusCode: http.StatusBadRequest,
   693  	},
   694  	ErrMissingSSECustomerKeyMD5: {
   695  		Code:           "InvalidArgument",
   696  		Description:    "Requests specifying Server Side Encryption with Customer provided keys must provide the client calculated MD5 of the secret key.",
   697  		HTTPStatusCode: http.StatusBadRequest,
   698  	},
   699  	ErrSSECustomerKeyMD5Mismatch: {
   700  		Code:           "InvalidArgument",
   701  		Description:    "The calculated MD5 hash of the key did not match the hash that was provided.",
   702  		HTTPStatusCode: http.StatusBadRequest,
   703  	},
   704  	ErrInvalidSSECustomerParameters: {
   705  		Code:           "InvalidArgument",
   706  		Description:    "The provided encryption parameters did not match the ones used originally.",
   707  		HTTPStatusCode: http.StatusBadRequest,
   708  	},
   709  	ErrIncompatibleEncryptionMethod: {
   710  		Code:           "InvalidArgument",
   711  		Description:    "Server side encryption specified with both SSE-C and SSE-S3 headers",
   712  		HTTPStatusCode: http.StatusBadRequest,
   713  	},
   714  	ErrKMSNotConfigured: {
   715  		Code:           "InvalidArgument",
   716  		Description:    "Server side encryption specified but KMS is not configured",
   717  		HTTPStatusCode: http.StatusBadRequest,
   718  	},
   719  	ErrKMSAuthFailure: {
   720  		Code:           "InvalidArgument",
   721  		Description:    "Server side encryption specified but KMS authorization failed",
   722  		HTTPStatusCode: http.StatusBadRequest,
   723  	},
   724  	ErrNoAccessKey: {
   725  		Code:           "AccessDenied",
   726  		Description:    "No AWSAccessKey was presented",
   727  		HTTPStatusCode: http.StatusForbidden,
   728  	},
   729  	ErrInvalidToken: {
   730  		Code:           "InvalidTokenId",
   731  		Description:    "The security token included in the request is invalid",
   732  		HTTPStatusCode: http.StatusForbidden,
   733  	},
   734  
   735  	// S3 extensions.
   736  	ErrContentSHA256Mismatch: {
   737  		Code:           "XAmzContentSHA256Mismatch",
   738  		Description:    "The provided 'x-amz-content-sha256' header does not match what was computed.",
   739  		HTTPStatusCode: http.StatusBadRequest,
   740  	},
   741  	ErrMaximumExpires: {
   742  		Code:           "AuthorizationQueryParametersError",
   743  		Description:    "X-Amz-Expires must be less than a week (in seconds); that is, the given X-Amz-Expires must be less than 604800 seconds",
   744  		HTTPStatusCode: http.StatusBadRequest,
   745  	},
   746  	ErrInvalidAPIVersion: {
   747  		Code:           "ErrInvalidAPIVersion",
   748  		Description:    "Invalid version found in the request",
   749  		HTTPStatusCode: http.StatusNotFound,
   750  	},
   751  
   752  	// LakeFS errors
   753  	ERRLakeFSNotSupported: {
   754  		Code:           "ERRLakeFSNotSupported",
   755  		Description:    "This operation is not supported in LakeFS",
   756  		HTTPStatusCode: http.StatusMethodNotAllowed,
   757  	},
   758  	ERRLakeFSWrongEndpoint: {
   759  		Code:           "ERRLakeFSWrongEndpoint",
   760  		Description:    "S3 request received in UI handler, did you forget to set your s3 gateway domain name?",
   761  		HTTPStatusCode: http.StatusNotFound,
   762  	},
   763  	ErrWriteToProtectedBranch: {
   764  		Code:           "ErrWriteToProtectedBranch",
   765  		Description:    "Attempted to write to a protected branch",
   766  		HTTPStatusCode: http.StatusForbidden,
   767  	},
   768  	ErrReadOnlyRepository: {
   769  		Code:           "ErrReadOnlyRepository",
   770  		Description:    "Attempted to write to a read-only repository",
   771  		HTTPStatusCode: http.StatusForbidden,
   772  	},
   773  }