Go errors are a specific type and that type is extensible. You can attach additional data to an error, and in recent versions of go you can wrap errors in other errors. You can do instance checking against an errors.New error, or do a type check against the kind of error you get back. This ultimately gives you significantly greater control and functionality over error codes.