{"record":{"id":"682d57381239ec68","repo":"influxdata/influxdb","slug":"failed-to-obtain-writer-handle-clone-0","errorCode":null,"errorMessage":"failed to obtain writer handle clone: {0}","messagePattern":"failed to obtain writer handle clone: (.+?)","errorType":"error_code","errorClass":"CodecError","httpStatus":null,"severity":"error","filePath":"core/parquet_file/src/serialize.rs","lineNumber":84,"sourceCode":"    NoRows,\n\n    /// A DataFusion error during the plan execution.\n    ///\n    /// Of note: a ResourcesExhaused error likely means the buffer\n    /// used for parquet data became too large.\n    #[error(transparent)]\n    DataFusion(Box<DataFusionError>),\n\n    /// Serialising the [`IoxMetadata`] to protobuf-encoded bytes failed.\n    #[error(\"failed to serialize iox metadata: {0}\")]\n    MetadataSerialisation(#[from] prost::EncodeError),\n\n    /// Writing the parquet file failed with the specified error.\n    #[error(\"failed to build parquet file: {0}\")]\n    Writer(#[from] ParquetError),\n\n    /// Attempting to clone a handle to the provided write sink failed.\n    #[error(\"failed to obtain writer handle clone: {0}\")]\n    CloneSink(std::io::Error),\n}\n\nimpl From<CodecError> for DataFusionError {\n    fn from(value: CodecError) -> Self {\n        match value {\n            e @ (CodecError::NoRecordBatches\n            | CodecError::NoRows\n            | CodecError::MetadataSerialisation(_)\n            | CodecError::CloneSink(_)) => Self::External(Box::new(e)),\n            CodecError::Writer(e) => Self::ParquetError(Box::new(e)),\n            CodecError::DataFusion(e) => *e,\n        }\n    }\n}\n\nimpl From<crate::writer::Error> for CodecError {\n    fn from(value: crate::writer::Error) -> Self {","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/core/parquet_file/src/serialize.rs#L66-L102","documentation":"CodecError::CloneSink, raised when cloning a handle to the provided write sink (a std::io::Error occurs while try_clone-ing the writer). The library needs a second handle to the sink (e.g. for buffered writing) and the sink type does not support cloning.","triggerScenarios":"Passing a Write+Seek sink whose try_clone() fails (e.g. certain non-cloneable file/socket wrappers) into the Parquet serialisation entry point that clones the handle.","commonSituations":"Wrapping a writer in a custom type without try_clone support, using a pipe or socket that cannot duplicate its descriptor, or the underlying fd being closed/unavailable.","solutions":["Use a sink type that supports try_clone, such as std::fs::File or std::io::Cursor","Write to an in-memory buffer (Vec<u8>/Cursor) and upload the bytes afterwards instead of a non-cloneable stream","Fix the custom writer wrapper to implement try_clone correctly","Check the inner std::io::Error for the OS-level reason (e.g. EMFILE, bad fd)"],"exampleFix":"// before: non-cloneable sink\nlet sink = MyStreamWrapper::new(sock);\nserialize_to_parquet(sink)?; // CloneSink error\n// after\nlet buf = std::io::Cursor::new(Vec::new());\nserialize_to_parquet(buf)?;\nupload(buf.into_inner());","handlingStrategy":"type-guard","validationCode":"// only pass sinks that can be cloned\nfn assert_cloneable<S: Write + Seek + TryClone>(_: &S) {}\n// or pre-check: use File/Cursor rather than custom wrappers","typeGuard":"fn is_cloneable_sink<S: Write + Seek>(s: &S) -> bool {\n    // File and Cursor support try_clone; custom wrappers may not\n    s.is_file() || std::mem::size_of::<*const S>() == std::mem::size_of::<*const std::fs::File>() && s.is_file()\n}","tryCatchPattern":"match res {\n    Err(CodecError::CloneSink(e)) => {\n        error!(%e, \"sink not cloneable; use File/Cursor or an in-memory buffer\")\n    }\n    other => other?,\n}","preventionTips":["Prefer std::fs::File or io::Cursor<Vec<u8>> as the write sink","Avoid wrapping sinks in custom types without try_clone support","Test the write path with the exact sink type used in production"],"tags":["io","writer","sink","clone"],"backgroundTag":"file-write-failed","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}