| Tested on | RHEL 10.2 with Go 1.27.0 |
|---|---|
| Package | strconv (Go 1.27.0 standard library) |
| Applies to | Any host with Go installed |
| Privilege | Normal user |
| Scope | Parse numeric strings to uint8 with ParseUint, handle syntax and range errors, hex and binary bases, read a string byte versus a Unicode character, and convert uint8 back to text. Does not cover general strconv or CSV parsing tutorials. |
| Related guides | Getting started with Go Golang strconv Golang int to int64 Golang byte to int Golang string contains |
Converting a string to uint8 in Go means one of two different things. Numeric text such as "255" must be parsed and validated for the 0–255 range. A character such as "A" is usually the first UTF-8 byte of the string, not a decimal parse.
| Input | Meaning | Method |
|---|---|---|
"123" |
Decimal number 123 | strconv.ParseUint(s, 10, 8) |
"FF" |
Hex number 255 | strconv.ParseUint(s, 16, 8) |
"A" |
First UTF-8 byte | s[0] after a length check |
"é" |
Unicode character | Work with rune; it may not fit in uint8 |
byte is an alias for uint8. The sections below follow numeric parsing first, then character bytes, then the reverse direction.
Search queries such as golang string to uint8 usually mean either parsing "255" as the number two hundred fifty-five or reading "A" as byte value sixty-five. Mixing those paths produces the wrong value or silent truncation, so pick the row in the table that matches your input.
Parse a numeric string to uint8
Use strconv.ParseUint when the string holds decimal digits that should become an unsigned byte value.
package main
import (
"fmt"
"strconv"
)
func main() {
s := "255"
n, err := strconv.ParseUint(s, 10, 8)
if err != nil {
fmt.Println("error:", err)
return
}
v := uint8(n)
fmt.Println(v)
}Save that program as main.go and run it from the module directory:
go run .On Go 1.27.0 with s := "255", the program prints the parsed byte value:
255ParseUint returns uint64, but the third argument bitSize is 8. That limits successful values to 0–255, so uint8(n) does not lose data after a successful parse. This is the primary answer for golang string to uint8 when the text is decimal digits.
Handle invalid and out-of-range values
Always check err before using n. Invalid syntax and out-of-range values fail at parse time:
package main
import (
"fmt"
"strconv"
)
func main() {
for _, s := range []string{"abc", "256", "-1"} {
_, err := strconv.ParseUint(s, 10, 8)
fmt.Printf("%q -> %v\n", s, err)
}
}Run the error-loop program the same way:
go run .Running that loop on Go 1.27.0 produces three distinct failure modes:
"abc" -> strconv.ParseUint: parsing "abc": invalid syntax
"256" -> strconv.ParseUint: parsing "256": value out of range
"-1" -> strconv.ParseUint: parsing "-1": invalid syntax"abc" is a syntax error. "256" exceeds an 8-bit unsigned range. "-1" fails because ParseUint does not accept a signed negative value.
strconv.ParseInt is intended for signed integers. fmt.Sscan can also scan directly into a uint8, but strconv.ParseUint(s, 10, 8) is more explicit and gives you strconv's structured syntax and range errors for this conversion.
You can distinguish range from syntax with errors.Is on strconv.ErrRange when you need that split; for most programs, handling any parse error together is enough.
Parse hexadecimal or binary strings to uint8
The same function accepts other bases when the text uses hex or binary digits:
hexv, _ := strconv.ParseUint("FF", 16, 8)
bin, _ := strconv.ParseUint("11111111", 2, 8)Both successful parses yield 255 as uint8. With base 0, ParseUint can infer prefixes such as 0xff, 0b11111111, or 0o377 from the string. Use base 16 or 2 when the input is known to be hex or binary without a prefix.
Hex and binary parsing still honors bitSize 8, so "100" in base 16 fails as out of range even though the digit string looks short.
Convert a character string to a byte
Reading "A" as the byte 65 is not numeric parsing. For ASCII text, the first byte of the string is the value you want:
s := "A"
if len(s) > 0 {
b := s[0] // b is uint8(65) for ASCII "A"
}Go strings are byte sequences. Text strings commonly contain UTF-8, so "é" occupies two UTF-8 bytes and s[0] returns only the first encoded byte.
If you need the Unicode code point, work with rune and remember that many code points exceed 255, so they do not fit in uint8. One string character does not always map to one uint8. Indexing s[0] on an empty string panics, so guard with len(s) > 0 first.
Why strconv.Atoi is not the best uint8 conversion
strconv.Atoi parses a signed int and does not enforce an 8-bit unsigned range:
package main
import (
"fmt"
"strconv"
)
func main() {
i, err := strconv.Atoi("300")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(uint8(i))
}Run that Atoi example to see the silent wrap:
go run .The wrapped value shows why Atoi is a poor fit for uint8:
44300 does not fit in uint8. The conversion to uint8 keeps only the low 8 bits, so you get 44 instead of an error. Use ParseUint(s, 10, 8) when the destination type must be uint8.
Convert uint8 back to string
The reverse direction also splits by meaning. A uint8 value can mean a small unsigned number, a Unicode code point, or one raw byte — and the string conversion differs.
For numeric text from uint8(123):
strconv.FormatUint(uint64(v), 10) // "123"To treat v as a Unicode code point:
s := string(rune(v)) // uint8(65) -> "A"; uint8(195) -> "Ã" (U+00C3)Integer-to-string conversion produces the UTF-8 encoding of that code point. string(rune(195)) is the character Ã, not a string that contains only the raw byte 0xC3.
To treat v as one raw byte:
s := string([]byte{v}) // preserves the byte value in the stringFor ASCII values 0–127, code point and raw byte coincide, so uint8(65) becomes "A" either way. Above that range, string(rune(v)) and string([]byte{v}) diverge.
Do not use this section as a general int-to-string guide. When the source is a wider integer type, see Golang strconv for formatting options.
Common mistakes
| Mistake | Correct approach |
|---|---|
Using Atoi and assuming the result is uint8 |
Use ParseUint(..., 8) |
| Ignoring parsing errors | Check err before casting |
Casting 300 to uint8 |
Validate range with ParseUint bitSize 8 |
Treating s[0] as a Unicode character |
It is one UTF-8 byte |
| Indexing an empty string | Check len(s) first |
Using ParseInt for an unsigned destination |
Prefer ParseUint |
References
- Package strconv — ParseUint
- The Go Programming Language Specification — Numeric types
- The Go Programming Language Specification — Conversions to and from string types
Summary
Parse decimal numeric text with strconv.ParseUint(s, 10, 8) and cast to uint8 after err is nil. The 8 bit size enforces the 0–255 range before the cast.
Reading a character byte uses s[0] when len(s) > 0, which is a UTF-8 byte and not always a full Unicode character. byte and uint8 are the same type.
Avoid strconv.Atoi for uint8 targets because oversized values wrap silently. Match the conversion to the meaning: digits in text versus a code point or raw byte.

