github.com/rbisecke/kafka-go@v0.4.27/error.go (about) 1 package kafka 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "syscall" 8 ) 9 10 // Error represents the different error codes that may be returned by kafka. 11 // https://kafka.apache.org/protocol#protocol_error_codes 12 type Error int 13 14 const ( 15 Unknown Error = -1 16 OffsetOutOfRange Error = 1 17 InvalidMessage Error = 2 18 UnknownTopicOrPartition Error = 3 19 InvalidMessageSize Error = 4 20 LeaderNotAvailable Error = 5 21 NotLeaderForPartition Error = 6 22 RequestTimedOut Error = 7 23 BrokerNotAvailable Error = 8 24 ReplicaNotAvailable Error = 9 25 MessageSizeTooLarge Error = 10 26 StaleControllerEpoch Error = 11 27 OffsetMetadataTooLarge Error = 12 28 NetworkException Error = 13 29 GroupLoadInProgress Error = 14 30 GroupCoordinatorNotAvailable Error = 15 31 NotCoordinatorForGroup Error = 16 32 InvalidTopic Error = 17 33 RecordListTooLarge Error = 18 34 NotEnoughReplicas Error = 19 35 NotEnoughReplicasAfterAppend Error = 20 36 InvalidRequiredAcks Error = 21 37 IllegalGeneration Error = 22 38 InconsistentGroupProtocol Error = 23 39 InvalidGroupId Error = 24 40 UnknownMemberId Error = 25 41 InvalidSessionTimeout Error = 26 42 RebalanceInProgress Error = 27 43 InvalidCommitOffsetSize Error = 28 44 TopicAuthorizationFailed Error = 29 45 GroupAuthorizationFailed Error = 30 46 ClusterAuthorizationFailed Error = 31 47 InvalidTimestamp Error = 32 48 UnsupportedSASLMechanism Error = 33 49 IllegalSASLState Error = 34 50 UnsupportedVersion Error = 35 51 TopicAlreadyExists Error = 36 52 InvalidPartitionNumber Error = 37 53 InvalidReplicationFactor Error = 38 54 InvalidReplicaAssignment Error = 39 55 InvalidConfiguration Error = 40 56 NotController Error = 41 57 InvalidRequest Error = 42 58 UnsupportedForMessageFormat Error = 43 59 PolicyViolation Error = 44 60 OutOfOrderSequenceNumber Error = 45 61 DuplicateSequenceNumber Error = 46 62 InvalidProducerEpoch Error = 47 63 InvalidTransactionState Error = 48 64 InvalidProducerIDMapping Error = 49 65 InvalidTransactionTimeout Error = 50 66 ConcurrentTransactions Error = 51 67 TransactionCoordinatorFenced Error = 52 68 TransactionalIDAuthorizationFailed Error = 53 69 SecurityDisabled Error = 54 70 BrokerAuthorizationFailed Error = 55 71 KafkaStorageError Error = 56 72 LogDirNotFound Error = 57 73 SASLAuthenticationFailed Error = 58 74 UnknownProducerId Error = 59 75 ReassignmentInProgress Error = 60 76 DelegationTokenAuthDisabled Error = 61 77 DelegationTokenNotFound Error = 62 78 DelegationTokenOwnerMismatch Error = 63 79 DelegationTokenRequestNotAllowed Error = 64 80 DelegationTokenAuthorizationFailed Error = 65 81 DelegationTokenExpired Error = 66 82 InvalidPrincipalType Error = 67 83 NonEmptyGroup Error = 68 84 GroupIdNotFound Error = 69 85 FetchSessionIDNotFound Error = 70 86 InvalidFetchSessionEpoch Error = 71 87 ListenerNotFound Error = 72 88 TopicDeletionDisabled Error = 73 89 FencedLeaderEpoch Error = 74 90 UnknownLeaderEpoch Error = 75 91 UnsupportedCompressionType Error = 76 92 StaleBrokerEpoch Error = 77 93 OffsetNotAvailable Error = 78 94 MemberIDRequired Error = 79 95 PreferredLeaderNotAvailable Error = 80 96 GroupMaxSizeReached Error = 81 97 FencedInstanceID Error = 82 98 EligibleLeadersNotAvailable Error = 83 99 ElectionNotNeeded Error = 84 100 NoReassignmentInProgress Error = 85 101 GroupSubscribedToTopic Error = 86 102 InvalidRecord Error = 87 103 UnstableOffsetCommit Error = 88 104 ) 105 106 // Error satisfies the error interface. 107 func (e Error) Error() string { 108 return fmt.Sprintf("[%d] %s: %s", e, e.Title(), e.Description()) 109 } 110 111 // Timeout returns true if the error was due to a timeout. 112 func (e Error) Timeout() bool { 113 return e == RequestTimedOut 114 } 115 116 // Temporary returns true if the operation that generated the error may succeed 117 // if retried at a later time. 118 // Kafka error documentation specifies these as "retriable" 119 // https://kafka.apache.org/protocol#protocol_error_codes 120 func (e Error) Temporary() bool { 121 switch e { 122 case InvalidMessage, 123 UnknownTopicOrPartition, 124 LeaderNotAvailable, 125 NotLeaderForPartition, 126 RequestTimedOut, 127 NetworkException, 128 GroupLoadInProgress, 129 GroupCoordinatorNotAvailable, 130 NotCoordinatorForGroup, 131 NotEnoughReplicas, 132 NotEnoughReplicasAfterAppend, 133 NotController, 134 KafkaStorageError, 135 FetchSessionIDNotFound, 136 InvalidFetchSessionEpoch, 137 ListenerNotFound, 138 FencedLeaderEpoch, 139 UnknownLeaderEpoch, 140 OffsetNotAvailable, 141 PreferredLeaderNotAvailable, 142 EligibleLeadersNotAvailable, 143 ElectionNotNeeded, 144 NoReassignmentInProgress, 145 GroupSubscribedToTopic, 146 UnstableOffsetCommit: 147 return true 148 default: 149 return false 150 } 151 } 152 153 // Title returns a human readable title for the error. 154 func (e Error) Title() string { 155 switch e { 156 case Unknown: 157 return "Unknown" 158 case OffsetOutOfRange: 159 return "Offset Out Of Range" 160 case InvalidMessage: 161 return "Invalid Message" 162 case UnknownTopicOrPartition: 163 return "Unknown Topic Or Partition" 164 case InvalidMessageSize: 165 return "Invalid Message Size" 166 case LeaderNotAvailable: 167 return "Leader Not Available" 168 case NotLeaderForPartition: 169 return "Not Leader For Partition" 170 case RequestTimedOut: 171 return "Request Timed Out" 172 case BrokerNotAvailable: 173 return "Broker Not Available" 174 case ReplicaNotAvailable: 175 return "Replica Not Available" 176 case MessageSizeTooLarge: 177 return "Message Size Too Large" 178 case StaleControllerEpoch: 179 return "Stale Controller Epoch" 180 case OffsetMetadataTooLarge: 181 return "Offset Metadata Too Large" 182 case GroupLoadInProgress: 183 return "Group Load In Progress" 184 case GroupCoordinatorNotAvailable: 185 return "Group Coordinator Not Available" 186 case NotCoordinatorForGroup: 187 return "Not Coordinator For Group" 188 case InvalidTopic: 189 return "Invalid Topic" 190 case RecordListTooLarge: 191 return "Record List Too Large" 192 case NotEnoughReplicas: 193 return "Not Enough Replicas" 194 case NotEnoughReplicasAfterAppend: 195 return "Not Enough Replicas After Append" 196 case InvalidRequiredAcks: 197 return "Invalid Required Acks" 198 case IllegalGeneration: 199 return "Illegal Generation" 200 case InconsistentGroupProtocol: 201 return "Inconsistent Group Protocol" 202 case InvalidGroupId: 203 return "Invalid Group ID" 204 case UnknownMemberId: 205 return "Unknown Member ID" 206 case InvalidSessionTimeout: 207 return "Invalid Session Timeout" 208 case RebalanceInProgress: 209 return "Rebalance In Progress" 210 case InvalidCommitOffsetSize: 211 return "Invalid Commit Offset Size" 212 case TopicAuthorizationFailed: 213 return "Topic Authorization Failed" 214 case GroupAuthorizationFailed: 215 return "Group Authorization Failed" 216 case ClusterAuthorizationFailed: 217 return "Cluster Authorization Failed" 218 case InvalidTimestamp: 219 return "Invalid Timestamp" 220 case UnsupportedSASLMechanism: 221 return "Unsupported SASL Mechanism" 222 case IllegalSASLState: 223 return "Illegal SASL State" 224 case UnsupportedVersion: 225 return "Unsupported Version" 226 case TopicAlreadyExists: 227 return "Topic Already Exists" 228 case InvalidPartitionNumber: 229 return "Invalid Partition Number" 230 case InvalidReplicationFactor: 231 return "Invalid Replication Factor" 232 case InvalidReplicaAssignment: 233 return "Invalid Replica Assignment" 234 case InvalidConfiguration: 235 return "Invalid Configuration" 236 case NotController: 237 return "Not Controller" 238 case InvalidRequest: 239 return "Invalid Request" 240 case UnsupportedForMessageFormat: 241 return "Unsupported For Message Format" 242 case PolicyViolation: 243 return "Policy Violation" 244 case OutOfOrderSequenceNumber: 245 return "Out Of Order Sequence Number" 246 case DuplicateSequenceNumber: 247 return "Duplicate Sequence Number" 248 case InvalidProducerEpoch: 249 return "Invalid Producer Epoch" 250 case InvalidTransactionState: 251 return "Invalid Transaction State" 252 case InvalidProducerIDMapping: 253 return "Invalid Producer ID Mapping" 254 case InvalidTransactionTimeout: 255 return "Invalid Transaction Timeout" 256 case ConcurrentTransactions: 257 return "Concurrent Transactions" 258 case TransactionCoordinatorFenced: 259 return "Transaction Coordinator Fenced" 260 case TransactionalIDAuthorizationFailed: 261 return "Transactional ID Authorization Failed" 262 case SecurityDisabled: 263 return "Security Disabled" 264 case BrokerAuthorizationFailed: 265 return "Broker Authorization Failed" 266 case KafkaStorageError: 267 return "Kafka Storage Error" 268 case LogDirNotFound: 269 return "Log Dir Not Found" 270 case SASLAuthenticationFailed: 271 return "SASL Authentication Failed" 272 case UnknownProducerId: 273 return "Unknown Producer ID" 274 case ReassignmentInProgress: 275 return "Reassignment In Progress" 276 case DelegationTokenAuthDisabled: 277 return "Delegation Token Auth Disabled" 278 case DelegationTokenNotFound: 279 return "Delegation Token Not Found" 280 case DelegationTokenOwnerMismatch: 281 return "Delegation Token Owner Mismatch" 282 case DelegationTokenRequestNotAllowed: 283 return "Delegation Token Request Not Allowed" 284 case DelegationTokenAuthorizationFailed: 285 return "Delegation Token Authorization Failed" 286 case DelegationTokenExpired: 287 return "Delegation Token Expired" 288 case InvalidPrincipalType: 289 return "Invalid Principal Type" 290 case NonEmptyGroup: 291 return "Non Empty Group" 292 case GroupIdNotFound: 293 return "Group ID Not Found" 294 case FetchSessionIDNotFound: 295 return "Fetch Session ID Not Found" 296 case InvalidFetchSessionEpoch: 297 return "Invalid Fetch Session Epoch" 298 case ListenerNotFound: 299 return "Listener Not Found" 300 case TopicDeletionDisabled: 301 return "Topic Deletion Disabled" 302 case FencedLeaderEpoch: 303 return "Fenced Leader Epoch" 304 case UnknownLeaderEpoch: 305 return "Unknown Leader Epoch" 306 case UnsupportedCompressionType: 307 return "Unsupported Compression Type" 308 case EligibleLeadersNotAvailable: 309 return "Eligible Leader Not Available" 310 case ElectionNotNeeded: 311 return "Election Not Needed" 312 case NoReassignmentInProgress: 313 return "No Reassignment In Progress" 314 case GroupSubscribedToTopic: 315 return "Group Subscribed To Topic" 316 case InvalidRecord: 317 return "Invalid Record" 318 case UnstableOffsetCommit: 319 return "Unstable Offset Commit" 320 } 321 return "" 322 } 323 324 // Description returns a human readable description of cause of the error. 325 func (e Error) Description() string { 326 switch e { 327 case Unknown: 328 return "an unexpected server error occurred" 329 case OffsetOutOfRange: 330 return "the requested offset is outside the range of offsets maintained by the server for the given topic/partition" 331 case InvalidMessage: 332 return "the message contents does not match its CRC" 333 case UnknownTopicOrPartition: 334 return "the request is for a topic or partition that does not exist on this broker" 335 case InvalidMessageSize: 336 return "the message has a negative size" 337 case LeaderNotAvailable: 338 return "the cluster is in the middle of a leadership election and there is currently no leader for this partition and hence it is unavailable for writes" 339 case NotLeaderForPartition: 340 return "the client attempted to send messages to a replica that is not the leader for some partition, the client's metadata are likely out of date" 341 case RequestTimedOut: 342 return "the request exceeded the user-specified time limit in the request" 343 case BrokerNotAvailable: 344 return "not a client facing error and is used mostly by tools when a broker is not alive" 345 case ReplicaNotAvailable: 346 return "a replica is expected on a broker, but is not (this can be safely ignored)" 347 case MessageSizeTooLarge: 348 return "the server has a configurable maximum message size to avoid unbounded memory allocation and the client attempted to produce a message larger than this maximum" 349 case StaleControllerEpoch: 350 return "internal error code for broker-to-broker communication" 351 case OffsetMetadataTooLarge: 352 return "the client specified a string larger than configured maximum for offset metadata" 353 case GroupLoadInProgress: 354 return "the broker returns this error code for an offset fetch request if it is still loading offsets (after a leader change for that offsets topic partition), or in response to group membership requests (such as heartbeats) when group metadata is being loaded by the coordinator" 355 case GroupCoordinatorNotAvailable: 356 return "the broker returns this error code for group coordinator requests, offset commits, and most group management requests if the offsets topic has not yet been created, or if the group coordinator is not active" 357 case NotCoordinatorForGroup: 358 return "the broker returns this error code if it receives an offset fetch or commit request for a group that it is not a coordinator for" 359 case InvalidTopic: 360 return "a request which attempted to access an invalid topic (e.g. one which has an illegal name), or if an attempt was made to write to an internal topic (such as the consumer offsets topic)" 361 case RecordListTooLarge: 362 return "a message batch in a produce request exceeds the maximum configured segment size" 363 case NotEnoughReplicas: 364 return "the number of in-sync replicas is lower than the configured minimum and requiredAcks is -1" 365 case NotEnoughReplicasAfterAppend: 366 return "the message was written to the log, but with fewer in-sync replicas than required." 367 case InvalidRequiredAcks: 368 return "the requested requiredAcks is invalid (anything other than -1, 1, or 0)" 369 case IllegalGeneration: 370 return "the generation id provided in the request is not the current generation" 371 case InconsistentGroupProtocol: 372 return "the member provided a protocol type or set of protocols which is not compatible with the current group" 373 case InvalidGroupId: 374 return "the group id is empty or null" 375 case UnknownMemberId: 376 return "the member id is not in the current generation" 377 case InvalidSessionTimeout: 378 return "the requested session timeout is outside of the allowed range on the broker" 379 case RebalanceInProgress: 380 return "the coordinator has begun rebalancing the group, the client should rejoin the group" 381 case InvalidCommitOffsetSize: 382 return "an offset commit was rejected because of oversize metadata" 383 case TopicAuthorizationFailed: 384 return "the client is not authorized to access the requested topic" 385 case GroupAuthorizationFailed: 386 return "the client is not authorized to access a particular group id" 387 case ClusterAuthorizationFailed: 388 return "the client is not authorized to use an inter-broker or administrative API" 389 case InvalidTimestamp: 390 return "the timestamp of the message is out of acceptable range" 391 case UnsupportedSASLMechanism: 392 return "the broker does not support the requested SASL mechanism" 393 case IllegalSASLState: 394 return "the request is not valid given the current SASL state" 395 case UnsupportedVersion: 396 return "the version of API is not supported" 397 case TopicAlreadyExists: 398 return "a topic with this name already exists" 399 case InvalidPartitionNumber: 400 return "the number of partitions is invalid" 401 case InvalidReplicationFactor: 402 return "the replication-factor is invalid" 403 case InvalidReplicaAssignment: 404 return "the replica assignment is invalid" 405 case InvalidConfiguration: 406 return "the configuration is invalid" 407 case NotController: 408 return "this is not the correct controller for this cluster" 409 case InvalidRequest: 410 return "this most likely occurs because of a request being malformed by the client library or the message was sent to an incompatible broker, se the broker logs for more details" 411 case UnsupportedForMessageFormat: 412 return "the message format version on the broker does not support the request" 413 case PolicyViolation: 414 return "the request parameters do not satisfy the configured policy" 415 case OutOfOrderSequenceNumber: 416 return "the broker received an out of order sequence number" 417 case DuplicateSequenceNumber: 418 return "the broker received a duplicate sequence number" 419 case InvalidProducerEpoch: 420 return "the producer attempted an operation with an old epoch, either there is a newer producer with the same transactional ID, or the producer's transaction has been expired by the broker" 421 case InvalidTransactionState: 422 return "the producer attempted a transactional operation in an invalid state" 423 case InvalidProducerIDMapping: 424 return "the producer attempted to use a producer id which is not currently assigned to its transactional ID" 425 case InvalidTransactionTimeout: 426 return "the transaction timeout is larger than the maximum value allowed by the broker (as configured by max.transaction.timeout.ms)" 427 case ConcurrentTransactions: 428 return "the producer attempted to update a transaction while another concurrent operation on the same transaction was ongoing" 429 case TransactionCoordinatorFenced: 430 return "the transaction coordinator sending a WriteTxnMarker is no longer the current coordinator for a given producer" 431 case TransactionalIDAuthorizationFailed: 432 return "the transactional ID authorization failed" 433 case SecurityDisabled: 434 return "the security features are disabled" 435 case BrokerAuthorizationFailed: 436 return "the broker authorization failed" 437 case KafkaStorageError: 438 return "disk error when trying to access log file on the disk" 439 case LogDirNotFound: 440 return "the user-specified log directory is not found in the broker config" 441 case SASLAuthenticationFailed: 442 return "SASL Authentication failed" 443 case UnknownProducerId: 444 return "the broker could not locate the producer metadata associated with the producer ID" 445 case ReassignmentInProgress: 446 return "a partition reassignment is in progress" 447 case DelegationTokenAuthDisabled: 448 return "delegation token feature is not enabled" 449 case DelegationTokenNotFound: 450 return "delegation token is not found on server" 451 case DelegationTokenOwnerMismatch: 452 return "specified principal is not valid owner/renewer" 453 case DelegationTokenRequestNotAllowed: 454 return "delegation token requests are not allowed on plaintext/1-way ssl channels and on delegation token authenticated channels" 455 case DelegationTokenAuthorizationFailed: 456 return "delegation token authorization failed" 457 case DelegationTokenExpired: 458 return "delegation token is expired" 459 case InvalidPrincipalType: 460 return "supplied principaltype is not supported" 461 case NonEmptyGroup: 462 return "the group is not empty" 463 case GroupIdNotFound: 464 return "the group ID does not exist" 465 case FetchSessionIDNotFound: 466 return "the fetch session ID was not found" 467 case InvalidFetchSessionEpoch: 468 return "the fetch session epoch is invalid" 469 case ListenerNotFound: 470 return "there is no listener on the leader broker that matches the listener on which metadata request was processed" 471 case TopicDeletionDisabled: 472 return "topic deletion is disabled" 473 case FencedLeaderEpoch: 474 return "the leader epoch in the request is older than the epoch on the broker" 475 case UnknownLeaderEpoch: 476 return "the leader epoch in the request is newer than the epoch on the broker" 477 case UnsupportedCompressionType: 478 return "the requesting client does not support the compression type of given partition" 479 case EligibleLeadersNotAvailable: 480 return "eligible topic partition leaders are not available" 481 case ElectionNotNeeded: 482 return "leader election not needed for topic partition" 483 case NoReassignmentInProgress: 484 return "no partition reassignment is in progress" 485 case GroupSubscribedToTopic: 486 return "deleting offsets of a topic is forbidden while the consumer group is actively subscribed to it" 487 case InvalidRecord: 488 return "this record has failed the validation on broker and hence be rejected" 489 case UnstableOffsetCommit: 490 return "there are unstable offsets that need to be cleared" 491 } 492 return "" 493 } 494 495 func isTimeout(err error) bool { 496 var timeoutError interface{ Timeout() bool } 497 if errors.As(err, &timeoutError) { 498 return timeoutError.Timeout() 499 } 500 return false 501 } 502 503 func isTemporary(err error) bool { 504 var tempError interface{ Temporary() bool } 505 if errors.As(err, &tempError) { 506 return tempError.Temporary() 507 } 508 return false 509 } 510 511 func isTransientNetworkError(err error) bool { 512 return errors.Is(err, io.ErrUnexpectedEOF) || 513 errors.Is(err, syscall.ECONNREFUSED) || 514 errors.Is(err, syscall.ECONNRESET) || 515 errors.Is(err, syscall.EPIPE) 516 } 517 518 func silentEOF(err error) error { 519 if err == io.EOF { 520 err = nil 521 } 522 return err 523 } 524 525 func dontExpectEOF(err error) error { 526 if err == io.EOF { 527 err = io.ErrUnexpectedEOF 528 } 529 return err 530 } 531 532 func coalesceErrors(errs ...error) error { 533 for _, err := range errs { 534 if err != nil { 535 return err 536 } 537 } 538 return nil 539 } 540 541 type MessageTooLargeError struct { 542 Message Message 543 Remaining []Message 544 } 545 546 func messageTooLarge(msgs []Message, i int) MessageTooLargeError { 547 remain := make([]Message, 0, len(msgs)-1) 548 remain = append(remain, msgs[:i]...) 549 remain = append(remain, msgs[i+1:]...) 550 return MessageTooLargeError{ 551 Message: msgs[i], 552 Remaining: remain, 553 } 554 } 555 556 func (e MessageTooLargeError) Error() string { 557 return MessageSizeTooLarge.Error() 558 } 559 560 func makeError(code int16, message string) error { 561 if code == 0 { 562 return nil 563 } 564 if message == "" { 565 return Error(code) 566 } 567 return fmt.Errorf("%w: %s", Error(code), message) 568 } 569 570 // WriteError is returned by kafka.(*Writer).WriteMessages when the writer is 571 // not configured to write messages asynchronously. WriteError values contain 572 // a list of errors where each entry matches the position of a message in the 573 // WriteMessages call. The program can determine the status of each message by 574 // looping over the error: 575 // 576 // switch err := w.WriteMessages(ctx, msgs...).(type) { 577 // case nil: 578 // case kafka.WriteErrors: 579 // for i := range msgs { 580 // if err[i] != nil { 581 // // handle the error writing msgs[i] 582 // ... 583 // } 584 // } 585 // default: 586 // // handle other errors 587 // ... 588 // } 589 // 590 type WriteErrors []error 591 592 // Count counts the number of non-nil errors in err. 593 func (err WriteErrors) Count() int { 594 n := 0 595 596 for _, e := range err { 597 if e != nil { 598 n++ 599 } 600 } 601 602 return n 603 } 604 605 func (err WriteErrors) Error() string { 606 return fmt.Sprintf("kafka write errors (%d/%d)", err.Count(), len(err)) 607 }