diff --git a/aya/src/programs/links.rs b/aya/src/programs/links.rs
index 8c315ff0..7e23f9f4 100644
--- a/aya/src/programs/links.rs
+++ b/aya/src/programs/links.rs
@@ -397,19 +397,6 @@ pub enum LinkError {
     SyscallError(#[from] SyscallError),
 }
 
-/// A [`Link`] identifier.
-pub struct LinkId(u32);
-
-impl LinkId {
-    /// Create a new [`LinkId`] from its kernel id.
-    ///
-    /// This method is unsafe since it doesn't check that the given `id` is a an
-    /// existing link id.
-    pub unsafe fn new(id: u32) -> Self {
-        Self(id)
-    }
-}
-
 #[derive(Debug)]
 pub(crate) enum LinkRef {
     Id(u32),
@@ -496,22 +483,6 @@ impl LinkOrder {
         })
     }
 
-    /// Attach before the link with the given id.
-    pub fn before_link_id(id: LinkId) -> Result<Self, LinkError> {
-        Ok(Self {
-            link_ref: LinkRef::Id(id.0),
-            flags: MprogFlags::BEFORE | MprogFlags::LINK | MprogFlags::ID,
-        })
-    }
-
-    /// Attach after the link with the given id.
-    pub fn after_link_id(id: LinkId) -> Result<Self, LinkError> {
-        Ok(Self {
-            link_ref: LinkRef::Id(id.0),
-            flags: MprogFlags::AFTER | MprogFlags::LINK | MprogFlags::ID,
-        })
-    }
-
     /// Attach before the given program.
     pub fn before_program<P: MultiProgProgram>(program: &P) -> Result<Self, ProgramError> {
         Ok(Self {
diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs
index 2c77a964..51565995 100644
--- a/aya/src/programs/mod.rs
+++ b/aya/src/programs/mod.rs
@@ -72,6 +72,7 @@ pub mod xdp;
 use std::{
     ffi::CString,
     io,
+    num::TryFromIntError,
     os::fd::{AsFd, AsRawFd, BorrowedFd},
     path::{Path, PathBuf},
     sync::Arc,
@@ -218,14 +219,9 @@ pub enum ProgramError {
     #[error(transparent)]
     IOError(#[from] io::Error),
 
-    /// An error occurred when attmpting to convert a type.
-    #[error("conversion error from {from} to {to}")]
-    ConversionError {
-        /// The type being converted from.
-        from: String,
-        /// The type being converted to.
-        to: String,
-    },
+    /// A checked integral type conversion failed.
+    #[error(transparent)]
+    TryFromIntError(#[from] TryFromIntError),
 }
 
 /// A [`Program`] file descriptor.
diff --git a/aya/src/programs/tc.rs b/aya/src/programs/tc.rs
index e8560078..794a72dc 100644
--- a/aya/src/programs/tc.rs
+++ b/aya/src/programs/tc.rs
@@ -269,12 +269,7 @@ impl SchedClassifier {
                 let name = CString::new(name).unwrap();
                 let (priority, handle) = unsafe {
                     netlink_qdisc_attach(
-                        if_index
-                            .try_into()
-                            .map_err(|_| ProgramError::ConversionError {
-                                from: "u32".to_string(),
-                                to: "i32".to_string(),
-                            })?,
+                        if_index.try_into()?,
                         &attach_type,
                         prog_fd,
                         &name,
@@ -366,13 +361,7 @@ impl Link for NlLink {
     }
 
     fn detach(self) -> Result<(), ProgramError> {
-        let if_index: i32 =
-            self.if_index
-                .try_into()
-                .map_err(|_| ProgramError::ConversionError {
-                    from: "u32".to_string(),
-                    to: "i32".to_string(),
-                })?;
+        let if_index: i32 = self.if_index.try_into()?;
         unsafe { netlink_qdisc_detach(if_index, &self.attach_type, self.priority, self.handle) }
             .map_err(|io_error| TcError::NetlinkError { io_error })?;
         Ok(())