 extension ServiceRecord: ResourceRecord {
     init(unpack data: Data, position: inout Data.Index, common: RecordCommonFields) throws {
         (name, _, unique, internetClass, ttl) = common
-        let length = try unpack(data, &position) as UInt16
+        let length = try UInt16(data: data, position: &position)
         let expectedPosition = position + Data.Index(length)
         priority = try unpack(data, &position)
         weight = try unpack(data, &position)
         port = try unpack(data, &position)
         server = try unpackName(data, &position)
-        precondition(position == expectedPosition, "Unexpected length")
+        guard position == expectedPosition else {
+            throw DecodeError.invalidDataSize
+        }
     }
 
     public func pack(onto buffer: inout Data, labels: inout Labels) throws {

        var other = [String]()
        while position < endIndex {
            let size = Int(try UInt8(data: data, position: &position))
            guard size > 0 else { break }
            var attr = String(bytes: data[position..<position+size], encoding: .utf8)!.characters.split(separator: "=", maxSplits: 1, omittingEmptySubsequences: false).map { String($0) }
            if attr.count == 2 {
                attrs[attr[0]] = attr[1]
            } else {
                other.append(attr[0])
            }
            position += size
        }
        self.attributes = attrs
        self.values = other

    case unicodeEncodingNotSupported
    case invalidIntegerSize
    case invalidResourceRecordType
    case invalidIPAddress
    case invalidDataSize
}

func unpackName(_ data: Data, _ position: inout Data.Index) throws -> String {
